diff --git a/src/common/api.c b/src/common/api.c index 5238c2e..1645f51 100644 --- a/src/common/api.c +++ b/src/common/api.c @@ -12,23 +12,13 @@ #include #include +#include #include "api.h" +#include "utils.h" #include "defines.h" /////////////////////////////// -// TODO: tmp -void powerOff(void) { - system("echo u > /proc/sysrq-trigger"); - system("echo s > /proc/sysrq-trigger"); - system("echo o > /proc/sysrq-trigger"); -} -void fauxSleep(void) { } -int preventAutosleep(void) { return 0; } -int isCharging() { return 0; } - -/////////////////////////////// - void LOG_note(int level, const char* fmt, ...) { char buf[1024] = {0}; va_list args; @@ -115,11 +105,11 @@ struct owlfb_mem_info { /////////////////////////////// +// NOTE: even with a buffer vsync blocks without threading + #define GFX_BUFFER_COUNT 3 #define GFX_ENABLE_VSYNC -// #define GFX_ENABLE_BUFFER - -// NOTE: even with a buffer vsync blocks without threading +#define GFX_ENABLE_BUFFER /////////////////////////////// @@ -176,7 +166,7 @@ SDL_Surface* GFX_init(void) { gfx.vinfo.xres_virtual = SCREEN_WIDTH; gfx.vinfo.yres_virtual = SCREEN_HEIGHT; #ifdef GFX_ENABLE_BUFFER - gfx.vinfo.yres_virtual *= GFX_BUFFER_COUNT + gfx.vinfo.yres_virtual *= GFX_BUFFER_COUNT; #endif #if defined (GFX_ENABLE_BUFFER) && !defined (GFX_ENABLE_VSYNC) gfx.vinfo.xoffset = 0; @@ -563,4 +553,77 @@ void PAD_poll(void) { int PAD_anyPressed(void) { return pad.is_pressed!=BTN_NONE; } int PAD_justPressed(int btn) { return pad.just_pressed & btn; } int PAD_isPressed(int btn) { return pad.is_pressed & btn; } -int PAD_justReleased(int btn) { return pad.just_released & btn; } \ No newline at end of file +int PAD_justReleased(int btn) { return pad.just_released & btn; } + +/////////////////////////////// + +static int can_poweroff = 1; +void POW_disablePowerOff(void) { + can_poweroff = 0; +} + +void POW_powerOff(void) { + if (can_poweroff) { + system("echo u > /proc/sysrq-trigger"); + system("echo s > /proc/sysrq-trigger"); + system("echo o > /proc/sysrq-trigger"); + } +} + +#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power" +#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" +static char governor[128]; + +static void POW_enterSleep(void) { + SetRawVolume(0); + putInt(BACKLIGHT_PATH, FB_BLANK_POWERDOWN); + // save current governor (either ondemand or performance) + getFile(GOVERNOR_PATH, governor, 128); + trimTrailingNewlines(governor); + + putFile(GOVERNOR_PATH, "powersave"); + sync(); +} +static void POW_exitSleep(void) { + putInt(BACKLIGHT_PATH, FB_BLANK_UNBLANK); + SetVolume(GetVolume()); + // restore previous governor + putFile(GOVERNOR_PATH, governor); +} +static void POW_waitForWake(void) { + SDL_Event event; + int wake = 0; + unsigned long sleep_ticks = SDL_GetTicks(); + while (!wake) { + while (SDL_PollEvent(&event)) { + if (event.type==SDL_KEYUP) { + uint8_t code = event.key.keysym.scancode; + if (code==CODE_POWER) { + wake = 1; + break; + } + } + } + SDL_Delay(200); + if (can_poweroff && SDL_GetTicks()-sleep_ticks>=120000) { // increased to two minutes + if (POW_isCharging()) sleep_ticks += 60000; // check again in a minute + else POW_powerOff(); // TODO: not working... + } + } + return; +} +void POW_fauxSleep(void) { + GFX_clear(gfx.screen); + PAD_reset(); + POW_enterSleep(); + // TODO: pause keymon + POW_waitForWake(); + // TODO: resume keymon + POW_exitSleep(); +} +int POW_preventAutosleep(void) { + return POW_isCharging(); +} +int POW_isCharging() { + return getInt("/sys/class/power_supply/battery/charger_online"); +} \ No newline at end of file diff --git a/src/common/api.h b/src/common/api.h index 7f9b575..46a5a89 100644 --- a/src/common/api.h +++ b/src/common/api.h @@ -4,11 +4,7 @@ /////////////////////////////// -// TODO: tmp -void powerOff(void); -void fauxSleep(void); -int preventAutosleep(void); -int isCharging(); +// TODO: tmo #define PAD_justRepeated PAD_justPressed /////////////////////////////// @@ -82,4 +78,12 @@ int PAD_justReleased(int btn); /////////////////////////////// +void POW_disablePowerOff(void); +void POW_powerOff(void); +void POW_fauxSleep(void); +int POW_preventAutosleep(void); +int POW_isCharging(); + +/////////////////////////////// + #endif diff --git a/src/minui/main.c b/src/minui/main.c index 154b7d3..094042f 100644 --- a/src/minui/main.c +++ b/src/minui/main.c @@ -1239,6 +1239,7 @@ int main (int argc, char *argv[]) { SDL_Surface* screen = GFX_init(); InitSettings(); + PAD_reset(); SDL_Surface* version = NULL; @@ -1249,7 +1250,7 @@ int main (int argc, char *argv[]) { PAD_reset(); int dirty = 1; - int was_charging = isCharging(); + int was_charging = POW_isCharging(); unsigned long charge_start = SDL_GetTicks(); int show_version = 0; int show_setting = 0; // 1=brightness,2=volume @@ -1399,7 +1400,7 @@ int main (int argc, char *argv[]) { #define CHARGE_DELAY 1000 if (dirty || now-charge_start>=CHARGE_DELAY) { - int is_charging = isCharging(); + int is_charging = POW_isCharging(); if (was_charging!=is_charging) { was_charging = is_charging; dirty = 1; @@ -1408,19 +1409,20 @@ int main (int argc, char *argv[]) { } if (power_start && now-power_start>=1000) { - powerOff(); - // return 0; // we should never reach this point + POW_powerOff(); + quit = 1; + break; } if (PAD_justPressed(BTN_SLEEP)) { power_start = now; } #define SLEEP_DELAY 30000 - if (now-cancel_start>=SLEEP_DELAY && preventAutosleep()) cancel_start = now; + if (now-cancel_start>=SLEEP_DELAY && POW_preventAutosleep()) cancel_start = now; if (now-cancel_start>=SLEEP_DELAY || PAD_justReleased(BTN_SLEEP)) // || PAD_justPressed(BTN_MENU)) { - fauxSleep(); + POW_fauxSleep(); cancel_start = SDL_GetTicks(); power_start = 0; dirty = 1; @@ -1553,11 +1555,11 @@ int main (int argc, char *argv[]) { if (dirty) { GFX_flip(screen); dirty = 0; - } - // slow down to 60fps - unsigned long frame_duration = SDL_GetTicks() - frame_start; - #define TARGET_FRAME_DURATION 17 - if (frame_duration