enlightenment/src/bin/e_powersave.c

181 lines
4.3 KiB
C

#include "e.h"
struct _E_Powersave_Deferred_Action
{
void (*func)(void *data);
const void *data;
unsigned char delete_me : 1;
};
/* local subsystem functions */
static Eina_Bool _e_powersave_cb_deferred_timer(void *data);
static void _e_powersave_mode_eval(void);
static void _e_powersave_event_update_free(void *data __UNUSED__, void *event);
/* local subsystem globals */
EAPI int E_EVENT_POWERSAVE_UPDATE = 0;
EAPI int E_EVENT_POWERSAVE_CONFIG_UPDATE = 0;
static int walking_deferred_actions = 0;
static Eina_List *deferred_actions = NULL;
static Ecore_Timer *deferred_timer = NULL;
static E_Powersave_Mode powersave_mode = E_POWERSAVE_MODE_LOW;
static double defer_time = 5.0;
/* externally accessible functions */
EINTERN int
e_powersave_init(void)
{
_e_powersave_mode_eval();
E_EVENT_POWERSAVE_UPDATE = ecore_event_type_new();
E_EVENT_POWERSAVE_CONFIG_UPDATE = ecore_event_type_new();
return 1;
}
EINTERN int
e_powersave_shutdown(void)
{
return 1;
}
EAPI E_Powersave_Deferred_Action *
e_powersave_deferred_action_add(void (*func)(void *data), const void *data)
{
E_Powersave_Deferred_Action *pa;
pa = calloc(1, sizeof(E_Powersave_Deferred_Action));
if (!pa) return NULL;
if (deferred_timer) ecore_timer_del(deferred_timer);
deferred_timer = ecore_timer_add(defer_time,
_e_powersave_cb_deferred_timer,
NULL);
pa->func = func;
pa->data = data;
deferred_actions = eina_list_append(deferred_actions, pa);
return pa;
}
EAPI void
e_powersave_deferred_action_del(E_Powersave_Deferred_Action *pa)
{
if (walking_deferred_actions)
{
pa->delete_me = 1;
return;
}
else
{
deferred_actions = eina_list_remove(deferred_actions, pa);
free(pa);
if (!deferred_actions)
{
if (deferred_timer)
{
ecore_timer_del(deferred_timer);
deferred_timer = NULL;
}
}
}
}
EAPI void
e_powersave_mode_set(E_Powersave_Mode mode)
{
E_Event_Powersave_Update *ev;
if (mode < e_config->powersave.min) mode = e_config->powersave.min;
else if (mode > e_config->powersave.max)
mode = e_config->powersave.max;
if (powersave_mode == mode) return;
printf("CHANGE PW SAVE MODE TO %i / %i\n", (int)mode, E_POWERSAVE_MODE_EXTREME);
powersave_mode = mode;
ev = E_NEW(E_Event_Powersave_Update, 1);
ev->mode = mode;
ecore_event_add(E_EVENT_POWERSAVE_UPDATE, ev, _e_powersave_event_update_free, NULL);
_e_powersave_mode_eval();
}
EAPI E_Powersave_Mode
e_powersave_mode_get(void)
{
return powersave_mode;
}
EAPI E_Powersave_Mode
e_powersave_mode_min_get(void)
{
return e_config->powersave.min;
}
EAPI E_Powersave_Mode
e_powersave_mode_max_get(void)
{
return e_config->powersave.max;
}
/* local subsystem functions */
static Eina_Bool
_e_powersave_cb_deferred_timer(void *data __UNUSED__)
{
E_Powersave_Deferred_Action *pa;
walking_deferred_actions++;
EINA_LIST_FREE(deferred_actions, pa)
{
if (!pa->delete_me) pa->func((void *)pa->data);
free(pa);
}
walking_deferred_actions--;
if (!deferred_actions) deferred_timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
static void
_e_powersave_mode_eval(void)
{
double t = 0.0;
switch (powersave_mode)
{
case E_POWERSAVE_MODE_NONE:
t = e_config->powersave.none; /* time to defer "power expensive" activities */
break;
case E_POWERSAVE_MODE_LOW:
t = e_config->powersave.low;
break;
case E_POWERSAVE_MODE_MEDIUM:
t = e_config->powersave.medium;
break;
case E_POWERSAVE_MODE_HIGH:
t = e_config->powersave.high;
break;
case E_POWERSAVE_MODE_EXTREME:
t = e_config->powersave.extreme;
break;
default:
return;
break;
}
if (t != defer_time)
{
if (deferred_timer) ecore_timer_del(deferred_timer);
deferred_timer = ecore_timer_add(defer_time,
_e_powersave_cb_deferred_timer,
NULL);
defer_time = t;
}
}
static void
_e_powersave_event_update_free(void *data __UNUSED__, void *event)
{
free(event);
}