2 #include "e_mod_main.h"
6 #include <sys/sysctl.h>
9 /* gadcon requirements */
10 static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
11 static void _gc_shutdown(E_Gadcon_Client *gcc);
12 static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
13 static const char *_gc_label(E_Gadcon_Client_Class *client_class);
14 static Evas_Object *_gc_icon(E_Gadcon_Client_Class *client_class, Evas *evas);
15 static const char *_gc_id_new(E_Gadcon_Client_Class *client_class);
16 /* and actually define the gadcon class that this module provides (just 1) */
17 static const E_Gadcon_Client_Class _gadcon_class =
19 GADCON_CLIENT_CLASS_VERSION, "cpufreq",
21 _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, NULL
23 E_GADCON_CLIENT_STYLE_PLAIN
26 /* actual module specifics */
27 typedef struct _Instance Instance;
35 static void _button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _menu_cb_post(void *data, E_Menu *m);
37 static void _cpufreq_set_governor(const char *governor);
38 static void _cpufreq_set_frequency(int frequency);
39 static Eina_Bool _cpufreq_cb_check(void *data);
40 static Status *_cpufreq_status_new();
41 static void _cpufreq_status_free(Status *s);
42 static int _cpufreq_status_check_available(Status *s);
43 static int _cpufreq_status_check_current(Status *s);
44 static int _cpufreq_cb_sort(const void *item1, const void *item2);
45 static void _cpufreq_face_update_available(Instance *inst);
46 static void _cpufreq_face_update_current(Instance *inst);
47 static void _cpufreq_face_cb_set_frequency(void *data, Evas_Object *o, const char *emission, const char *source);
48 static void _cpufreq_face_cb_set_governor(void *data, Evas_Object *o, const char *emission, const char *source);
49 static Eina_Bool _cpufreq_event_cb_powersave(void *data __UNUSED__, int type, void *event);
51 static void _cpufreq_menu_fast(void *data, E_Menu *m, E_Menu_Item *mi);
52 static void _cpufreq_menu_medium(void *data, E_Menu *m, E_Menu_Item *mi);
53 static void _cpufreq_menu_normal(void *data, E_Menu *m, E_Menu_Item *mi);
54 static void _cpufreq_menu_slow(void *data, E_Menu *m, E_Menu_Item *mi);
55 static void _cpufreq_menu_very_slow(void *data, E_Menu *m, E_Menu_Item *mi);
56 static void _cpufreq_menu_restore_governor(void *data, E_Menu *m, E_Menu_Item *mi);
57 static void _cpufreq_menu_auto_powersave(void *data, E_Menu *m, E_Menu_Item *mi);
58 static void _cpufreq_menu_governor(void *data, E_Menu *m, E_Menu_Item *mi);
59 static void _cpufreq_menu_powersave_governor(void *data, E_Menu *m, E_Menu_Item *mi);
60 static void _cpufreq_menu_frequency(void *data, E_Menu *m, E_Menu_Item *mi);
61 static void _cpufreq_poll_interval_update(void);
63 static E_Config_DD *conf_edd = NULL;
65 Config *cpufreq_config = NULL;
67 static E_Gadcon_Client *
68 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
74 inst = E_NEW(Instance, 1);
76 o = edje_object_add(gc->evas);
77 e_theme_edje_object_set(o, "base/theme/modules/cpufreq",
78 "e/modules/cpufreq/main");
79 edje_object_signal_callback_add(o, "e,action,governor,next", "*",
80 _cpufreq_face_cb_set_governor, NULL);
81 edje_object_signal_callback_add(o, "e,action,frequency,increase", "*",
82 _cpufreq_face_cb_set_frequency, NULL);
83 edje_object_signal_callback_add(o, "e,action,frequency,decrease", "*",
84 _cpufreq_face_cb_set_frequency, NULL);
86 gcc = e_gadcon_client_new(gc, name, id, style, o);
92 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
93 _button_cb_mouse_down, inst);
94 cpufreq_config->instances =
95 eina_list_append(cpufreq_config->instances, inst);
96 if (cpufreq_config->status) _cpufreq_status_free(cpufreq_config->status);
97 cpufreq_config->status = _cpufreq_status_new();
98 _cpufreq_cb_check(NULL);
99 _cpufreq_face_update_available(inst);
101 cpufreq_config->handler =
102 ecore_event_handler_add(E_EVENT_POWERSAVE_UPDATE,
103 _cpufreq_event_cb_powersave, NULL);
108 _gc_shutdown(E_Gadcon_Client *gcc)
113 cpufreq_config->instances =
114 eina_list_remove(cpufreq_config->instances, inst);
115 evas_object_del(inst->o_cpu);
118 if (cpufreq_config->handler)
119 ecore_event_handler_del(cpufreq_config->handler);
123 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient __UNUSED__)
125 e_gadcon_client_aspect_set(gcc, 16, 16);
126 e_gadcon_client_min_size_set(gcc, 16, 16);
130 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
136 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
141 o = edje_object_add(evas);
142 snprintf(buf, sizeof(buf), "%s/e-module-cpufreq.edj",
143 e_module_dir_get(cpufreq_config->module));
144 edje_object_file_set(o, buf, "icon");
149 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
151 static char idbuff[32];
153 snprintf(idbuff, sizeof(idbuff), "%s.%d", _gadcon_class.name,
154 eina_list_count(cpufreq_config->instances));
159 _button_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
162 Evas_Event_Mouse_Down *ev;
164 if (cpufreq_config->menu) return;
178 cpufreq_config->menu_poll = mo;
180 mi = e_menu_item_new(mo);
181 e_menu_item_label_set(mi, _("Fast (4 ticks)"));
182 e_menu_item_radio_set(mi, 1);
183 e_menu_item_radio_group_set(mi, 1);
184 if (cpufreq_config->poll_interval <= 4) e_menu_item_toggle_set(mi, 1);
185 e_menu_item_callback_set(mi, _cpufreq_menu_fast, NULL);
187 mi = e_menu_item_new(mo);
188 e_menu_item_label_set(mi, _("Medium (8 ticks)"));
189 e_menu_item_radio_set(mi, 1);
190 e_menu_item_radio_group_set(mi, 1);
191 if (cpufreq_config->poll_interval > 4) e_menu_item_toggle_set(mi, 1);
192 e_menu_item_callback_set(mi, _cpufreq_menu_medium, NULL);
194 mi = e_menu_item_new(mo);
195 e_menu_item_label_set(mi, _("Normal (32 ticks)"));
196 e_menu_item_radio_set(mi, 1);
197 e_menu_item_radio_group_set(mi, 1);
198 if (cpufreq_config->poll_interval >= 32) e_menu_item_toggle_set(mi, 1);
199 e_menu_item_callback_set(mi, _cpufreq_menu_normal, NULL);
201 mi = e_menu_item_new(mo);
202 e_menu_item_label_set(mi, _("Slow (64 ticks)"));
203 e_menu_item_radio_set(mi, 1);
204 e_menu_item_radio_group_set(mi, 1);
205 if (cpufreq_config->poll_interval >= 64) e_menu_item_toggle_set(mi, 1);
206 e_menu_item_callback_set(mi, _cpufreq_menu_slow, NULL);
208 mi = e_menu_item_new(mo);
209 e_menu_item_label_set(mi, _("Very Slow (256 ticks)"));
210 e_menu_item_radio_set(mi, 1);
211 e_menu_item_radio_group_set(mi, 1);
212 if (cpufreq_config->poll_interval >= 128)
213 e_menu_item_toggle_set(mi, 1);
214 e_menu_item_callback_set(mi, _cpufreq_menu_very_slow, NULL);
216 if (cpufreq_config->status->governors)
219 cpufreq_config->menu_governor = mo;
221 for (l = cpufreq_config->status->governors; l; l = l->next)
223 mi = e_menu_item_new(mo);
224 if (!strcmp(l->data, "userspace"))
225 e_menu_item_label_set(mi, _("Manual"));
226 else if (!strcmp(l->data, "ondemand"))
227 e_menu_item_label_set(mi, _("Automatic"));
228 else if (!strcmp(l->data, "conservative"))
229 e_menu_item_label_set(mi, _("Lower Power Automatic"));
230 else if (!strcmp(l->data, "powersave"))
231 e_menu_item_label_set(mi, _("Minimum Speed"));
232 else if (!strcmp(l->data, "performance"))
233 e_menu_item_label_set(mi, _("Maximum Speed"));
234 e_menu_item_radio_set(mi, 1);
235 e_menu_item_radio_group_set(mi, 1);
236 if (!strcmp(cpufreq_config->status->cur_governor, l->data))
237 e_menu_item_toggle_set(mi, 1);
238 e_menu_item_callback_set(mi, _cpufreq_menu_governor, l->data);
241 e_menu_item_separator_set(e_menu_item_new(mo), 1);
243 mi = e_menu_item_new(mo);
244 e_menu_item_label_set(mi, _("Restore CPU Power Policy"));
245 e_menu_item_check_set(mi, 1);
246 e_menu_item_toggle_set(mi, cpufreq_config->restore_governor);
247 e_menu_item_callback_set(mi, _cpufreq_menu_restore_governor, NULL);
250 cpufreq_config->menu_powersave = mo;
252 for (l = cpufreq_config->status->governors; l; l = l->next)
254 if (!strcmp(l->data, "userspace"))
257 mi = e_menu_item_new(mo);
258 if (!strcmp(l->data, "ondemand"))
259 e_menu_item_label_set(mi, _("Automatic"));
260 else if (!strcmp(l->data, "conservative"))
261 e_menu_item_label_set(mi, _("Lower Power Automatic"));
262 else if (!strcmp(l->data, "powersave"))
263 e_menu_item_label_set(mi, _("Minimum Speed"));
264 else if (!strcmp(l->data, "performance"))
265 e_menu_item_label_set(mi, _("Maximum Speed"));
267 e_menu_item_radio_set(mi, 1);
268 e_menu_item_radio_group_set(mi, 1);
269 if (cpufreq_config->powersave_governor
270 && !strcmp(cpufreq_config->powersave_governor, l->data))
271 e_menu_item_toggle_set(mi, 1);
272 e_menu_item_callback_set(mi, _cpufreq_menu_powersave_governor, l->data);
275 e_menu_item_separator_set(e_menu_item_new(mo), 1);
277 mi = e_menu_item_new(mo);
278 e_menu_item_label_set(mi, _("Automatic powersaving"));
279 e_menu_item_check_set(mi, 1);
280 e_menu_item_toggle_set(mi, cpufreq_config->auto_powersave);
281 e_menu_item_callback_set(mi, _cpufreq_menu_auto_powersave, NULL);
284 if ((cpufreq_config->status->frequencies) &&
285 (cpufreq_config->status->can_set_frequency))
288 cpufreq_config->menu_frequency = mo;
290 for (l = cpufreq_config->status->frequencies; l; l = l->next)
294 frequency = (long)l->data;
295 mi = e_menu_item_new(mo);
296 if (frequency < 1000000)
297 snprintf(buf, sizeof(buf), _("%i MHz"), frequency / 1000);
299 snprintf(buf, sizeof(buf), _("%i.%i GHz"),
300 frequency / 1000000, (frequency % 1000000) / 100000);
301 buf[sizeof(buf) - 1] = 0;
302 e_menu_item_label_set(mi, buf);
303 e_menu_item_radio_set(mi, 1);
304 e_menu_item_radio_group_set(mi, 1);
305 if (cpufreq_config->status->cur_frequency == frequency)
306 e_menu_item_toggle_set(mi, 1);
307 e_menu_item_callback_set(mi, _cpufreq_menu_frequency, l->data);
312 mi = e_menu_item_new(mg);
313 e_menu_item_label_set(mi, _("Time Between Updates"));
314 e_menu_item_submenu_set(mi, cpufreq_config->menu_poll);
316 if (cpufreq_config->menu_governor)
318 mi = e_menu_item_new(mg);
319 e_menu_item_label_set(mi, _("Set CPU Power Policy"));
320 e_menu_item_submenu_set(mi, cpufreq_config->menu_governor);
323 if (cpufreq_config->menu_frequency)
325 mi = e_menu_item_new(mg);
326 e_menu_item_label_set(mi, _("Set CPU Speed"));
327 e_menu_item_submenu_set(mi, cpufreq_config->menu_frequency);
329 if (cpufreq_config->menu_powersave)
331 mi = e_menu_item_new(mg);
332 e_menu_item_label_set(mi, _("Powersaving behavior"));
333 e_menu_item_submenu_set(mi, cpufreq_config->menu_powersave);
336 e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
337 &cx, &cy, NULL, NULL);
338 cpufreq_config->menu = mg;
339 e_menu_post_deactivate_callback_set(mg, _menu_cb_post, inst);
341 e_gadcon_locked_set(inst->gcc->gadcon, 1);
343 e_menu_activate_mouse(mg,
344 e_util_zone_current_get(e_manager_current_get()),
345 cx + ev->output.x, cy + ev->output.y, 1, 1,
346 E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
348 else if (ev->button == 3)
354 m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
355 cpufreq_config->menu = m;
356 e_menu_post_deactivate_callback_set(m, _menu_cb_post, NULL);
358 e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
359 &cx, &cy, NULL, NULL);
361 e_menu_activate_mouse(m,
362 e_util_zone_current_get(e_manager_current_get()),
363 cx + ev->output.x, cy + ev->output.y, 1, 1,
364 E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
369 _menu_cb_post(void *data, E_Menu *m __UNUSED__)
371 Instance *inst = data;
374 e_gadcon_locked_set(inst->gcc->gadcon, 0);
376 if (!cpufreq_config->menu) return;
377 e_object_del(E_OBJECT(cpufreq_config->menu));
378 cpufreq_config->menu = NULL;
379 if (cpufreq_config->menu_poll)
380 e_object_del(E_OBJECT(cpufreq_config->menu_poll));
381 cpufreq_config->menu_poll = NULL;
382 if (cpufreq_config->menu_governor)
383 e_object_del(E_OBJECT(cpufreq_config->menu_governor));
384 cpufreq_config->menu_governor = NULL;
385 if (cpufreq_config->menu_frequency)
386 e_object_del(E_OBJECT(cpufreq_config->menu_frequency));
387 cpufreq_config->menu_frequency = NULL;
388 if (cpufreq_config->menu_powersave)
389 e_object_del(E_OBJECT(cpufreq_config->menu_powersave));
390 cpufreq_config->menu_powersave = NULL;
394 _cpufreq_set_governor(const char *governor)
399 snprintf(buf, sizeof(buf),
400 "%s %s %s", cpufreq_config->set_exe_path, "governor", governor);
407 con = e_container_current_get(e_manager_current_get());
408 if (!(dia = e_dialog_new(con, "E", "_e_mod_cpufreq_error_setfreq")))
410 e_dialog_title_set(dia, "Enlightenment Cpufreq Module");
411 e_dialog_icon_set(dia, "enlightenment", 64);
412 e_dialog_text_set(dia, _("There was an error trying to set the<br>"
413 "cpu frequency governor via the module's<br>"
414 "setfreq utility."));
415 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
416 e_win_centered_set(dia->win, 1);
422 _cpufreq_set_frequency(int frequency)
430 if (!cpufreq_config->status->can_set_frequency)
435 con = e_container_current_get(e_manager_current_get());
436 if (!(dia = e_dialog_new(con, "E", "_e_mod_cpufreq_error_setfreq")))
438 e_dialog_title_set(dia, "Enlightenment Cpufreq Module");
439 e_dialog_icon_set(dia, "enlightenment", 64);
440 e_dialog_text_set(dia, _("Your kernel does not support setting the<br>"
441 "CPU frequency at all. You may be missing<br>"
442 "Kernel modules or features, or your CPU<br>"
443 "simply does not support this feature."));
444 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
445 e_win_centered_set(dia->win, 1);
450 // change it to "userspace"
451 _cpufreq_set_governor("userspace");
453 snprintf(buf, sizeof(buf),
454 "%s %s %i", cpufreq_config->set_exe_path, "frequency", frequency);
461 con = e_container_current_get(e_manager_current_get());
462 if (!(dia = e_dialog_new(con, "E", "_e_mod_cpufreq_error_setfreq")))
464 e_dialog_title_set(dia, "Enlightenment Cpufreq Module");
465 e_dialog_icon_set(dia, "enlightenment", 64);
466 e_dialog_text_set(dia, _("There was an error trying to set the<br>"
467 "cpu frequency setting via the module's<br>"
468 "setfreq utility."));
469 e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
470 e_win_centered_set(dia->win, 1);
476 _cpufreq_cb_check(void *data __UNUSED__)
482 if (cpufreq_config->menu_poll) return ECORE_CALLBACK_RENEW;
483 active = cpufreq_config->status->active;
484 if (_cpufreq_status_check_current(cpufreq_config->status))
486 for (l = cpufreq_config->instances; l; l = l->next)
489 _cpufreq_face_update_current(inst);
492 if (active != cpufreq_config->status->active)
494 for (l = cpufreq_config->instances; l; l = l->next)
497 if (cpufreq_config->status->active == 0)
498 edje_object_signal_emit(inst->o_cpu, "e,state,disabled", "e");
499 else if (cpufreq_config->status->active == 1)
500 edje_object_signal_emit(inst->o_cpu, "e,state,enabled", "e");
504 return ECORE_CALLBACK_RENEW;
508 _cpufreq_status_new()
512 s = E_NEW(Status, 1);
519 _cpufreq_status_free(Status *s)
523 if (s->frequencies) eina_list_free(s->frequencies);
526 for (l = s->governors; l; l = l->next) free(l->data);
527 eina_list_free(s->governors);
529 if (s->cur_governor) free(s->cur_governor);
530 if (s->orig_governor) eina_stringshare_del(s->orig_governor);
535 _cpufreq_cb_sort(const void *item1, const void *item2)
541 if (a < b) return -1;
542 else if (a > b) return 1;
547 _cpufreq_status_check_available(Status *s)
551 // FIXME: this sssumes all cores accept the same freqs/ might be wrong
555 char *freqs, *pos, *q;
557 /* read freq_levels sysctl and store it in freq */
559 if (sysctlbyname("dev.cpu.0.freq_levels", buf, &len, NULL, 0) == 0)
561 /* sysctl returns 0 on success */
564 eina_list_free(s->frequencies);
565 s->frequencies = NULL;
568 /* parse freqs and store the frequencies in s->frequencies */
572 q = strchr(pos, '/');
578 s->frequencies = eina_list_append(s->frequencies, (void *)freq);
581 pos = strchr(pos, ' ');
585 /* sort is not necessary because freq_levels is already sorted */
586 /* freebsd doesn't have governors */
589 for (l = s->governors; l; l = l->next) free(l->data);
590 eina_list_free(s->governors);
596 f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r");
603 eina_list_free(s->frequencies);
604 s->frequencies = NULL;
607 fgets(buf, sizeof(buf), f);
608 buf[sizeof(buf) - 1] = 0;
611 freq = strtok(buf, " ");
616 s->frequencies = eina_list_append(s->frequencies,
617 (void *) (long)atoi(freq));
619 freq = strtok(NULL, " ");
623 s->frequencies = eina_list_sort(s->frequencies,
624 eina_list_count(s->frequencies),
628 f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", "r");
635 for (l = s->governors; l; l = l->next)
637 eina_list_free(s->governors);
641 fgets(buf, sizeof(buf), f);
642 buf[sizeof(buf) - 1] = 0;
645 gov = strtok(buf, " ");
648 while ((*gov) && (isspace(*gov))) gov++;
649 if (strlen(gov) != 0)
650 s->governors = eina_list_append(s->governors, strdup(gov));
651 gov = strtok(NULL, " ");
656 eina_list_sort(s->governors, eina_list_count(s->governors),
657 (int (*)(const void *, const void *))strcmp);
664 _cpufreq_status_check_current(Status *s)
671 int frequency_min = 0x7fffffff;
672 int frequency_max = 0;
678 /* frequency is stored in dev.cpu.0.freq */
679 if (sysctlbyname("dev.cpu.0.freq", &frequency, &len, NULL, 0) == 0)
682 if (frequency != s->cur_frequency) ret = 1;
683 s->cur_frequency = frequency;
687 /* hardcoded for testing */
688 s->can_set_frequency = 1;
689 s->cur_governor = NULL;
693 _cpufreq_status_check_available(s);
694 // average out frequencies of all cores
695 for (i = 0; i < 64; i++)
697 snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_cur_freq", i);
701 fgets(buf, sizeof(buf), f);
702 buf[sizeof(buf) - 1] = 0;
705 frequency = atoi(buf);
706 if (frequency > frequency_max) frequency_max = frequency;
707 if (frequency < frequency_min) frequency_min = frequency;
708 freqtot += frequency;
715 frequency = freqtot / i;
716 if (frequency != s->cur_frequency) ret = 1;
717 if (frequency_min != s->cur_min_frequency) ret = 1;
718 if (frequency_max != s->cur_max_frequency) ret = 1;
719 s->cur_frequency = frequency;
720 s->cur_min_frequency = frequency_min;
721 s->cur_max_frequency = frequency_max;
723 // printf("%i | %i %i\n", frequency, frequency_min, frequency_max);
725 // FIXME: this sssumes all cores are on the same governor
726 f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "r");
729 s->can_set_frequency = 1;
734 s->can_set_frequency = 0;
737 f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r");
743 fgets(buf, sizeof(buf), f);
744 buf[sizeof(buf) - 1] = 0;
746 for (p = buf; (*p != 0) && (isalnum(*p)); p++);
749 if ((!s->cur_governor) || (strcmp(buf, s->cur_governor)))
753 if (s->cur_governor) free(s->cur_governor);
754 s->cur_governor = strdup(buf);
756 for (i = strlen(s->cur_governor) - 1; i >= 0; i--)
758 if (isspace(s->cur_governor[i]))
759 s->cur_governor[i] = 0;
770 _cpufreq_face_update_available(Instance *inst)
772 Edje_Message_Int_Set *frequency_msg;
773 Edje_Message_String_Set *governor_msg;
778 count = eina_list_count(cpufreq_config->status->frequencies);
779 frequency_msg = malloc(sizeof(Edje_Message_Int_Set) + (count - 1) * sizeof(int));
780 EINA_SAFETY_ON_NULL_RETURN(frequency_msg);
781 frequency_msg->count = count;
782 for (l = cpufreq_config->status->frequencies, i = 0; l; l = l->next, i++)
783 frequency_msg->val[i] = (long)l->data;
784 edje_object_message_send(inst->o_cpu, EDJE_MESSAGE_INT_SET, 1, frequency_msg);
787 count = eina_list_count(cpufreq_config->status->governors);
788 governor_msg = malloc(sizeof(Edje_Message_String_Set) + (count - 1) * sizeof(char *));
789 governor_msg->count = count;
790 for (l = cpufreq_config->status->governors, i = 0; l; l = l->next, i++)
791 governor_msg->str[i] = (char *)l->data;
792 edje_object_message_send(inst->o_cpu, EDJE_MESSAGE_STRING_SET, 2, governor_msg);
797 _cpufreq_face_update_current(Instance *inst)
799 Edje_Message_Int_Set *frequency_msg;
800 Edje_Message_String governor_msg;
802 frequency_msg = malloc(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 4));
803 EINA_SAFETY_ON_NULL_RETURN(frequency_msg);
804 frequency_msg->count = 5;
805 frequency_msg->val[0] = cpufreq_config->status->cur_frequency;
806 frequency_msg->val[1] = cpufreq_config->status->can_set_frequency;
807 frequency_msg->val[2] = cpufreq_config->status->cur_min_frequency;
808 frequency_msg->val[3] = cpufreq_config->status->cur_max_frequency;
809 frequency_msg->val[4] = 0; // pad
810 edje_object_message_send(inst->o_cpu, EDJE_MESSAGE_INT_SET, 3,
814 /* BSD crashes here without the if-condition
815 * since it has no governors (yet) */
816 if (cpufreq_config->status->cur_governor)
818 governor_msg.str = cpufreq_config->status->cur_governor;
819 edje_object_message_send(inst->o_cpu, EDJE_MESSAGE_STRING, 4,
825 _cpufreq_face_cb_set_frequency(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission, const char *src __UNUSED__)
828 int next_frequency = 0;
830 for (l = cpufreq_config->status->frequencies; l; l = l->next)
832 if (cpufreq_config->status->cur_frequency == (long)l->data)
834 if (!strcmp(emission, "e,action,frequency,increase"))
836 if (l->next) next_frequency = (long)l->next->data;
839 else if (!strcmp(emission, "e,action,frequency,decrease"))
841 if (l->prev) next_frequency = (long)l->prev->data;
848 if (next_frequency != 0) _cpufreq_set_frequency(next_frequency);
852 _cpufreq_face_cb_set_governor(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *src __UNUSED__)
855 char *next_governor = NULL;
857 for (l = cpufreq_config->status->governors; l; l = l->next)
859 if (!strcmp(l->data, cpufreq_config->status->cur_governor))
862 next_governor = l->next->data;
864 next_governor = cpufreq_config->status->governors->data;
868 if (next_governor) _cpufreq_set_governor(next_governor);
872 _cpufreq_event_cb_powersave(void *data __UNUSED__, int type, void *event)
874 E_Event_Powersave_Update *ev;
876 Eina_Bool has_powersave = EINA_FALSE;
877 Eina_Bool has_conservative = EINA_FALSE;
879 if (type != E_EVENT_POWERSAVE_UPDATE) return ECORE_CALLBACK_PASS_ON;
880 if (!cpufreq_config->auto_powersave) return ECORE_CALLBACK_PASS_ON;
883 if (!cpufreq_config->status->orig_governor)
884 cpufreq_config->status->orig_governor = eina_stringshare_add(cpufreq_config->status->cur_governor);
886 for (l = cpufreq_config->status->governors; l; l = l->next)
888 if (!strcmp(l->data, "conservative"))
889 has_conservative = EINA_TRUE;
890 else if (!strcmp(l->data, "powersave"))
891 has_powersave = EINA_TRUE;
896 case E_POWERSAVE_MODE_NONE:
897 case E_POWERSAVE_MODE_LOW:
898 _cpufreq_set_governor(cpufreq_config->status->orig_governor);
899 eina_stringshare_del(cpufreq_config->status->orig_governor);
900 cpufreq_config->status->orig_governor = NULL;
902 case E_POWERSAVE_MODE_MEDIUM:
903 case E_POWERSAVE_MODE_HIGH:
904 if ((cpufreq_config->powersave_governor) || (has_conservative))
906 if (cpufreq_config->powersave_governor)
907 _cpufreq_set_governor(cpufreq_config->powersave_governor);
909 _cpufreq_set_governor("conservative");
912 case E_POWERSAVE_MODE_EXTREME:
914 _cpufreq_set_governor("powersave");
918 return ECORE_CALLBACK_PASS_ON;
922 _cpufreq_menu_fast(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
924 cpufreq_config->poll_interval = 4;
925 _cpufreq_poll_interval_update();
929 _cpufreq_menu_medium(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
931 cpufreq_config->poll_interval = 8;
932 _cpufreq_poll_interval_update();
936 _cpufreq_menu_normal(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
938 cpufreq_config->poll_interval = 32;
939 _cpufreq_poll_interval_update();
943 _cpufreq_menu_slow(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
945 cpufreq_config->poll_interval = 64;
946 _cpufreq_poll_interval_update();
950 _cpufreq_menu_very_slow(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
952 cpufreq_config->poll_interval = 256;
953 _cpufreq_poll_interval_update();
957 _cpufreq_menu_restore_governor(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi)
959 cpufreq_config->restore_governor = e_menu_item_toggle_get(mi);
960 if ((!cpufreq_config->governor) ||
961 (strcmp(cpufreq_config->status->cur_governor, cpufreq_config->governor)))
963 eina_stringshare_replace(&cpufreq_config->governor,
964 cpufreq_config->status->cur_governor);
966 e_config_save_queue();
970 _cpufreq_menu_auto_powersave(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi)
972 cpufreq_config->auto_powersave = e_menu_item_toggle_get(mi);
973 e_config_save_queue();
977 _cpufreq_menu_governor(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
979 const char *governor;
984 _cpufreq_set_governor(governor);
985 eina_stringshare_replace(&cpufreq_config->governor, governor);
987 e_config_save_queue();
991 _cpufreq_menu_powersave_governor(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
993 const char *governor;
997 eina_stringshare_replace(&cpufreq_config->powersave_governor, governor);
998 e_config_save_queue();
1002 _cpufreq_menu_frequency(void * data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1006 frequency = (long)data;
1007 if (frequency > 0) _cpufreq_set_frequency(frequency);
1011 _cpufreq_poll_interval_update(void)
1013 if (cpufreq_config->frequency_check_poller)
1014 ecore_poller_del(cpufreq_config->frequency_check_poller);
1015 cpufreq_config->frequency_check_poller =
1016 ecore_poller_add(ECORE_POLLER_CORE, cpufreq_config->poll_interval,
1017 _cpufreq_cb_check, NULL);
1018 e_config_save_queue();
1022 EAPI E_Module_Api e_modapi =
1024 E_MODULE_API_VERSION, "Cpufreq"
1028 e_modapi_init(E_Module *m)
1033 conf_edd = E_CONFIG_DD_NEW("Cpufreq_Config", Config);
1038 E_CONFIG_VAL(D, T, config_version, INT);
1039 E_CONFIG_VAL(D, T, poll_interval, INT);
1040 E_CONFIG_VAL(D, T, restore_governor, INT);
1041 E_CONFIG_VAL(D, T, auto_powersave, INT);
1042 E_CONFIG_VAL(D, T, powersave_governor, STR);
1043 E_CONFIG_VAL(D, T, governor, STR);
1045 cpufreq_config = e_config_domain_load("module.cpufreq", conf_edd);
1046 if ((cpufreq_config) &&
1047 (cpufreq_config->config_version != CPUFREQ_CONFIG_VERSION))
1048 E_FREE(cpufreq_config);
1050 if (!cpufreq_config)
1052 cpufreq_config = E_NEW(Config, 1);
1053 cpufreq_config->config_version = CPUFREQ_CONFIG_VERSION;
1054 cpufreq_config->poll_interval = 32;
1055 cpufreq_config->restore_governor = 0;
1056 cpufreq_config->auto_powersave = 1;
1057 cpufreq_config->powersave_governor = NULL;
1058 cpufreq_config->governor = NULL;
1060 E_CONFIG_LIMIT(cpufreq_config->poll_interval, 1, 1024);
1062 snprintf(buf, sizeof(buf), "%s/%s/freqset",
1063 e_module_dir_get(m), MODULE_ARCH);
1064 cpufreq_config->set_exe_path = strdup(buf);
1065 cpufreq_config->frequency_check_poller =
1066 ecore_poller_add(ECORE_POLLER_CORE, cpufreq_config->poll_interval,
1067 _cpufreq_cb_check, NULL);
1068 cpufreq_config->status = _cpufreq_status_new();
1070 _cpufreq_status_check_available(cpufreq_config->status);
1071 if ((cpufreq_config->restore_governor) && (cpufreq_config->governor))
1073 /* If the governor is available, restore it */
1074 for (l = cpufreq_config->status->governors; l; l = l->next)
1076 if (!strcmp(l->data, cpufreq_config->governor))
1078 _cpufreq_set_governor(cpufreq_config->governor);
1084 cpufreq_config->module = m;
1086 e_gadcon_provider_register(&_gadcon_class);
1091 e_modapi_shutdown(E_Module *m __UNUSED__)
1093 e_gadcon_provider_unregister(&_gadcon_class);
1095 if (cpufreq_config->frequency_check_poller)
1096 ecore_poller_del(cpufreq_config->frequency_check_poller);
1097 if (cpufreq_config->menu)
1099 e_menu_post_deactivate_callback_set(cpufreq_config->menu, NULL, NULL);
1100 e_object_del(E_OBJECT(cpufreq_config->menu));
1101 cpufreq_config->menu = NULL;
1103 if (cpufreq_config->menu_poll)
1105 e_menu_post_deactivate_callback_set(cpufreq_config->menu_poll, NULL, NULL);
1106 e_object_del(E_OBJECT(cpufreq_config->menu_poll));
1107 cpufreq_config->menu_poll = NULL;
1109 if (cpufreq_config->menu_governor)
1111 e_menu_post_deactivate_callback_set(cpufreq_config->menu_governor, NULL, NULL);
1112 e_object_del(E_OBJECT(cpufreq_config->menu_governor));
1113 cpufreq_config->menu_governor = NULL;
1115 if (cpufreq_config->menu_frequency)
1117 e_menu_post_deactivate_callback_set(cpufreq_config->menu_frequency, NULL, NULL);
1118 e_object_del(E_OBJECT(cpufreq_config->menu_frequency));
1119 cpufreq_config->menu_frequency = NULL;
1121 if (cpufreq_config->menu_powersave)
1123 e_menu_post_deactivate_callback_set(cpufreq_config->menu_powersave, NULL, NULL);
1124 e_object_del(E_OBJECT(cpufreq_config->menu_powersave));
1125 cpufreq_config->menu_powersave = NULL;
1127 if (cpufreq_config->governor)
1128 eina_stringshare_del(cpufreq_config->governor);
1129 if (cpufreq_config->status) _cpufreq_status_free(cpufreq_config->status);
1130 E_FREE(cpufreq_config->set_exe_path);
1131 free(cpufreq_config);
1132 cpufreq_config = NULL;
1133 E_CONFIG_DD_FREE(conf_edd);
1138 e_modapi_save(E_Module *m __UNUSED__)
1140 e_config_domain_save("module.cpufreq", conf_edd, cpufreq_config);