--- epplets/E-Power.c.orig 2011-11-26 11:38:40.000000000 +0100 +++ epplets/E-Power.c 2012-10-10 15:01:17.000000000 +0200 @@ -1,9 +1,22 @@ +/*- + * Copyright 2008, Pietro Cerutti (FreeBSD adaptation) + */ + #define _GNU_SOURCE #include "epplet.h" #include #include #include +#ifdef __FreeBSD__ +#include +#include +#include +#ifdef __i386__ +#include +#endif +#endif + /* Modified by Attila ZIMLER , 2003/11/16 Added ACPI power management support. */ @@ -11,6 +24,20 @@ /* Length of explain strings in /proc/acpi/battery/BAT0 data files */ #define DATA_EXPLAIN_STR_LEN 25 +/* Power management modes */ +#define MODE_NONE 0x0 +#define MODE_APM 0x1 +#define MODE_ACPI 0x2 +#define MODE_SYS 0x3 +static unsigned mode = MODE_NONE; + +#ifdef __FreeBSD__ +#define ACPI_DEV "/dev/acpi" +#define APM_DEV "/dev/apm" +static int apm_fd = -1, + acpi_fd = -1; +#endif + int prev_bat_val = 110; int bat_val = 0; int time_val = 0; @@ -33,14 +60,37 @@ static void cb_timer(void *data) { +#ifdef linux struct stat st; if ((stat("/proc/apm", &st) > -1) && S_ISREG(st.st_mode)) - cb_timer_apm(data); + mode = MODE_APM; else if ((stat("/proc/acpi/battery", &st) > -1) && S_ISDIR(st.st_mode)) - cb_timer_acpi(data); + mode = MODE_ACPI; else if ((stat("/sys/class/power_supply", &st) > -1) && S_ISDIR(st.st_mode)) - cb_timer_sys(data); + mode = MODE_SYS; + else + mode = MODE_NONE; +#elif defined (__FreeBSD__) + /* + * Try ACPI first, if it doesn't work, revert to APM + */ + if (acpi_fd != 1 || ((acpi_fd = open(ACPI_DEV, O_RDONLY)) != -1)) + mode = MODE_ACPI; + else if (apm_fd != 1 || (apm_fd = open(APM_DEV, O_RDONLY)) != -1) + mode = MODE_APM; + else + mode = MODE_NONE; +#else + mode = MODE_NONE; +#endif + + if (mode & MODE_APM) + cb_timer_apm(data); + else if (mode & MODE_ACPI) + cb_timer_acpi(data); + else if (mode & MODE_SYS) + tb_timer_sys(data); } static void @@ -61,9 +111,8 @@ int bat_level = 0; int bat_drain = 1; - int bat_val = 0; - char current_status[256]; + char *line = 0; size_t lsize = 0; int discharging = 0; @@ -77,6 +126,8 @@ int hours, minutes; +#ifdef linux + /* Read some information on first run. */ dirp = opendir("/proc/acpi/battery"); if (dirp) @@ -207,27 +258,74 @@ else snprintf(current_status, sizeof(current_status), "Full"); + /* Final steps before ending the status update. */ + data = NULL; + if (lsize) + free(line); + +#elif defined(__FreeBSD__) + union acpi_battery_ioctl_arg batt; + int c; + batt.unit = 0; + if(ioctl(acpi_fd, ACPIIO_BATT_GET_BATTINFO, &batt) == -1) + return; + + /* + * Get percent + */ + if(batt.battinfo.cap == -1) { + c = snprintf(current_status, sizeof(current_status), "???"); + bat_val = 0; + } + else { + c = snprintf(current_status, sizeof(current_status), "%d%%", + batt.battinfo.cap); + bat_val = batt.battinfo.cap; + } + + /* + * Get online status + */ + if(batt.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT) + c += snprintf(¤t_status[c], sizeof(current_status) - c, " NONE\n"); + else if(batt.battinfo.state == ACPI_BATT_STAT_DISCHARG || batt.battinfo.state == ACPI_BATT_STAT_CRITICAL) + c += snprintf(¤t_status[c], sizeof(current_status) - c, " OFF\n"); + else + c += snprintf(¤t_status[c], sizeof(current_status) - c, " ON\n"); + + /* + * Get remaining time + */ + if(batt.battinfo.min == -1) { + if(batt.battinfo.state == ACPI_BATT_STAT_DISCHARG || + batt.battinfo.state == ACPI_BATT_STAT_CRITICAL || + batt.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT) + snprintf(¤t_status[c], sizeof(current_status) - c, "?:??"); + } + else { + snprintf(¤t_status[c], sizeof(current_status) - c, "%d:%2d", + batt.battinfo.min / 60, batt.battinfo.min % 60); + } + +#endif /* Display current status */ Epplet_change_label(label, current_status); sprintf(current_status, "E-Power-Bat-%i.png", ((bat_val + 5) / 10) * 10); Epplet_change_image(image, 44, 24, current_status); Epplet_timer(cb_timer, NULL, 5.0, "TIMER"); - - /* Final steps before ending the status update. */ - data = NULL; - if (lsize) - free(line); } static void cb_timer_apm(void *data) { + char s[256]; +#ifdef linux static FILE *f; f = fopen("/proc/apm", "r"); if (f) { - char s[256], s1[32], s2[32], s3[32]; + char s1[32], s2[32], s3[32]; int apm_flags, ac_stat, bat_stat, bat_flags; int i, hours, minutes, up, up2; char *s_ptr; @@ -300,14 +398,57 @@ else s_ptr += sprintf(s_ptr, "%i:%02i", hours, minutes); } - Epplet_change_label(label, s); + prev_bat_val = bat_val; +#elif defined(__FreeBSD__) && defined(__i386__) + struct apm_info apm; + int c; + if(ioctl(apm_fd, APMIO_GETINFO, &apm) == -1) + return; + + /* + * Get percent + */ + if(apm.ai_batt_life == 0xff) { + c = snprintf(s, sizeof(s), "???"); + bat_val = 0; + } + else { + c = snprintf(s, sizeof(s), "%d%%", apm.ai_batt_life); + bat_val = apm.ai_batt_life; + } + + /* + * Get online status + */ + if(apm.ai_acline == 0xff) + c += snprintf(&s[c], sizeof(s) - c, " NONE\n"); + else if(apm.ai_acline) + c += snprintf(&s[c], sizeof(s) - c, " ON\n"); + else + c += snprintf(&s[c], sizeof(s) - c , " OFF\n"); + + /* + * Get remaining time + */ + if(apm.ai_batt_time == -1) { + if(apm.ai_acline == 0xff || !apm.ai_acline) + snprintf(&s[c], sizeof(s) - c, "?:??"); + } + else + snprintf(&s[c], sizeof(s) - c, "%d:%2d", + apm.ai_batt_time / 3600, apm.ai_batt_time / 60 % 60); +#endif + /* Display current status */ + Epplet_change_label(label, s); sprintf(s, "E-Power-Bat-%i.png", ((bat_val + 5) / 10) * 10); Epplet_change_image(image, 44, 24, s); +#ifdef linux Epplet_timer(cb_timer, NULL, 30.0, "TIMER"); +#else + Epplet_timer(cb_timer, NULL, 5.0, "TIMER"); +#endif - prev_bat_val = bat_val; - } data = NULL; } @@ -530,7 +671,14 @@ static void cb_suspend(void *data) { +#ifdef __FreeBSD__ + if(mode & MODE_ACPI) + system("/usr/sbin/acpiconf -s 5"); + else if(mode & MODE_APM) + system("/usr/sbin/apm -z"); +#else system("/usr/bin/apm -s"); +#endif return; data = NULL; } @@ -538,7 +686,14 @@ static void cb_sleep(void *data) { +#ifdef __FreeBSD__ + if(mode & MODE_ACPI) + system("/usr/sbin/acpiconf -s 1"); + else if(mode & MODE_APM) + system("/usr/sbin/amp -z"); +#else system("/usr/bin/apm -S"); +#endif return; data = NULL; }