Merge branch 'misc-battery-updates' into 'master'
Misc battery updates Hi, So here are a couple of more patches. I did only minimal testing for the battery BSD stuff (basically compilation under Linux and check, that only sensible errors appear). The second patch (remove static clock tooltip buffer) is independent of the remaining changes, but depends on the first patch. I guess the battery code for Linux could be further improved by using libudev to handle kernel events for added batteries and AC plug changes. -- Sebastian See merge request !8
This commit is contained in:
commit
8528a6a4a4
16 changed files with 488 additions and 194 deletions
|
@ -78,7 +78,20 @@ set( SOURCES src/config.c
|
|||
src/util/window.c )
|
||||
|
||||
if( ENABLE_BATTERY )
|
||||
set( SOURCES ${SOURCES} src/battery/battery.c src/battery/linux.c)
|
||||
set( SOURCES ${SOURCES} src/battery/battery.c)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set( SOURCES ${SOURCES} src/battery/linux.c)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
set( SOURCES ${SOURCES} src/battery/freebsd.c)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
set( SOURCES ${SOURCES} src/battery/openbsd.c)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||
set( SOURCES ${SOURCES} src/battery/openbsd.c)
|
||||
else(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set( SOURCES ${SOURCES} src/battery/dummy.c)
|
||||
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
|
||||
add_definitions( -DENABLE_BATTERY )
|
||||
endif( ENABLE_BATTERY )
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Tint2 : battery
|
||||
* Tint2 : Generic battery
|
||||
*
|
||||
* Copyright (C) 2009-2015 Sebastian Reichel <sre@ring0.de>
|
||||
*
|
||||
|
@ -24,18 +24,6 @@
|
|||
#include <cairo-xlib.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#include <machine/apmvar.h>
|
||||
#include <err.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "window.h"
|
||||
#include "server.h"
|
||||
#include "panel.h"
|
||||
|
@ -56,6 +44,8 @@ static char buf_bat_time[20];
|
|||
|
||||
int8_t battery_low_status;
|
||||
unsigned char battery_low_cmd_sent;
|
||||
char *ac_connected_cmd;
|
||||
char *ac_disconnected_cmd;
|
||||
char *battery_low_cmd;
|
||||
char *battery_lclick_command;
|
||||
char *battery_mclick_command;
|
||||
|
@ -64,10 +54,6 @@ char *battery_uwheel_command;
|
|||
char *battery_dwheel_command;
|
||||
int battery_found;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
int apm_fd;
|
||||
#endif
|
||||
|
||||
void update_battery_tick(void* arg)
|
||||
{
|
||||
if (!battery_enabled)
|
||||
|
@ -75,6 +61,7 @@ void update_battery_tick(void* arg)
|
|||
|
||||
int old_found = battery_found;
|
||||
int old_percentage = battery_state.percentage;
|
||||
int old_ac_connected = battery_state.ac_connected;
|
||||
int16_t old_hours = battery_state.time.hours;
|
||||
int8_t old_minutes = battery_state.time.minutes;
|
||||
|
||||
|
@ -87,6 +74,14 @@ void update_battery_tick(void* arg)
|
|||
// Try again
|
||||
update_battery();
|
||||
}
|
||||
|
||||
if (old_ac_connected != battery_state.ac_connected) {
|
||||
if(battery_state.ac_connected)
|
||||
tint_exec(ac_connected_cmd);
|
||||
else
|
||||
tint_exec(ac_disconnected_cmd);
|
||||
}
|
||||
|
||||
if (old_found == battery_found &&
|
||||
old_percentage == battery_state.percentage &&
|
||||
old_hours == battery_state.time.hours &&
|
||||
|
@ -154,9 +149,6 @@ void default_battery()
|
|||
battery_state.time.minutes = 0;
|
||||
battery_state.time.seconds = 0;
|
||||
battery_state.state = BATTERY_UNKNOWN;
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
apm_fd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cleanup_battery()
|
||||
|
@ -181,51 +173,22 @@ void cleanup_battery()
|
|||
battery_timeout = NULL;
|
||||
battery_found = 0;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
if ((apm_fd != -1) && (close(apm_fd) == -1))
|
||||
warn("cannot close /dev/apm");
|
||||
apm_fd = -1;
|
||||
#elif defined(__linux)
|
||||
free_linux_batteries();
|
||||
#endif
|
||||
battery_os_free();
|
||||
}
|
||||
|
||||
void init_battery()
|
||||
{
|
||||
if (!battery_enabled)
|
||||
return;
|
||||
battery_found = 0;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
if (apm_fd > 0)
|
||||
close(apm_fd);
|
||||
apm_fd = open("/dev/apm", O_RDONLY);
|
||||
if (apm_fd < 0) {
|
||||
warn("ERROR: battery applet cannot open /dev/apm.");
|
||||
battery_found = 0;
|
||||
} else {
|
||||
battery_found = 1;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
battery_found = (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
||||
#elif defined(__linux)
|
||||
battery_found = init_linux_batteries();
|
||||
#endif
|
||||
battery_found = battery_os_init();
|
||||
|
||||
if (!battery_timeout)
|
||||
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
|
||||
}
|
||||
|
||||
const char* battery_get_tooltip(void* obj) {
|
||||
#if defined(__linux)
|
||||
return linux_batteries_get_tooltip();
|
||||
#else
|
||||
return g_strdup("No tooltip support for this OS!");
|
||||
#endif
|
||||
char* battery_get_tooltip(void* obj) {
|
||||
return battery_os_tooltip();
|
||||
}
|
||||
|
||||
void init_battery_panel(void *p)
|
||||
|
@ -258,105 +221,22 @@ void init_battery_panel(void *p)
|
|||
|
||||
|
||||
int update_battery() {
|
||||
int64_t energy_now = 0,
|
||||
energy_full = 0;
|
||||
int seconds = 0;
|
||||
int8_t new_percentage = 0;
|
||||
int errors = 0;
|
||||
int err;
|
||||
|
||||
/* reset */
|
||||
battery_state.state = BATTERY_UNKNOWN;
|
||||
battery_state.percentage = 0;
|
||||
battery_state.ac_connected = FALSE;
|
||||
batstate_set_time(&battery_state, 0);
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
struct apm_power_info info;
|
||||
if (apm_fd > 0 && ioctl(apm_fd, APM_IOC_GETPOWER, &(info)) == 0) {
|
||||
// best attempt at mapping to Linux battery states
|
||||
switch (info.battery_state) {
|
||||
case APM_BATT_CHARGING:
|
||||
battery_state.state = BATTERY_CHARGING;
|
||||
break;
|
||||
default:
|
||||
battery_state.state = BATTERY_DISCHARGING;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.battery_life == 100)
|
||||
battery_state.state = BATTERY_FULL;
|
||||
|
||||
// no mapping for openbsd really
|
||||
energy_full = 0;
|
||||
energy_now = 0;
|
||||
|
||||
if (info.minutes_left != -1)
|
||||
seconds = info.minutes_left * 60;
|
||||
else
|
||||
seconds = -1;
|
||||
|
||||
new_percentage = info.battery_life;
|
||||
} else {
|
||||
warn("power update: APM_IOC_GETPOWER");
|
||||
errors = 1;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) {
|
||||
// attemp to map the battery state to Linux
|
||||
battery_state.state = BATTERY_UNKNOWN;
|
||||
switch(sysctl_out) {
|
||||
case 1:
|
||||
battery_state.state = BATTERY_DISCHARGING;
|
||||
break;
|
||||
case 2:
|
||||
battery_state.state = BATTERY_CHARGING;
|
||||
break;
|
||||
default:
|
||||
battery_state.state = BATTERY_FULL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "power update: no such sysctl");
|
||||
errors = 1;
|
||||
}
|
||||
|
||||
// no mapping for freebsd
|
||||
energy_full = 0;
|
||||
energy_now = 0;
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) != 0)
|
||||
seconds = -1;
|
||||
else
|
||||
seconds = sysctl_out * 60;
|
||||
|
||||
// charging or error
|
||||
if (seconds < 0)
|
||||
seconds = 0;
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) != 0)
|
||||
new_percentage = -1;
|
||||
else
|
||||
new_percentage = sysctl_out;
|
||||
#else
|
||||
update_linux_batteries(&battery_state.state, &energy_now, &energy_full, &seconds);
|
||||
#endif
|
||||
|
||||
battery_state.time.hours = seconds / 3600;
|
||||
seconds -= 3600 * battery_state.time.hours;
|
||||
battery_state.time.minutes = seconds / 60;
|
||||
seconds -= 60 * battery_state.time.minutes;
|
||||
battery_state.time.seconds = seconds;
|
||||
|
||||
if (energy_full > 0)
|
||||
new_percentage = 0.5 + ((energy_now <= energy_full ? energy_now : energy_full) * 100.0) / energy_full;
|
||||
|
||||
battery_state.percentage = new_percentage;
|
||||
err = battery_os_update(&battery_state);
|
||||
|
||||
// clamp percentage to 100 in case battery is misreporting that its current charge is more than its max
|
||||
if (battery_state.percentage > 100) {
|
||||
battery_state.percentage = 100;
|
||||
}
|
||||
|
||||
return errors;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef struct batstate {
|
|||
int percentage;
|
||||
struct battime time;
|
||||
enum chargestate state;
|
||||
gboolean ac_connected;
|
||||
} batstate;
|
||||
|
||||
extern struct batstate battery_state;
|
||||
|
@ -56,6 +57,9 @@ extern int percentage_hide;
|
|||
extern int8_t battery_low_status;
|
||||
extern char *battery_low_cmd;
|
||||
|
||||
extern char *ac_connected_cmd;
|
||||
extern char *ac_disconnected_cmd;
|
||||
|
||||
extern char *battery_lclick_command;
|
||||
extern char *battery_mclick_command;
|
||||
extern char *battery_rclick_command;
|
||||
|
@ -76,6 +80,14 @@ static inline gchar* chargestate2str(enum chargestate state) {
|
|||
};
|
||||
}
|
||||
|
||||
static inline void batstate_set_time(struct batstate *state, int seconds) {
|
||||
state->time.hours = seconds / 3600;
|
||||
seconds -= 3600 * state->time.hours;
|
||||
state->time.minutes = seconds / 60;
|
||||
seconds -= 60 * state->time.minutes;
|
||||
state->time.seconds = seconds;
|
||||
}
|
||||
|
||||
// default global data
|
||||
void default_battery();
|
||||
|
||||
|
@ -93,11 +105,10 @@ int resize_battery(void *obj);
|
|||
|
||||
void battery_action(int button);
|
||||
|
||||
#ifdef __linux
|
||||
gboolean init_linux_batteries();
|
||||
void free_linux_batteries();
|
||||
void update_linux_batteries(enum chargestate *state, gint64 *energy_now, gint64 *energy_full, int *seconds);
|
||||
const char* linux_batteries_get_tooltip();
|
||||
#endif
|
||||
/* operating system specific functions */
|
||||
gboolean battery_os_init();
|
||||
void battery_os_free();
|
||||
int battery_os_update(struct batstate *state);
|
||||
char* battery_os_tooltip();
|
||||
|
||||
#endif
|
||||
|
|
40
src/battery/dummy.c
Normal file
40
src/battery/dummy.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Tint2 : Dummy battery (non-functional)
|
||||
*
|
||||
* Copyright (C) 2015 Sebastian Reichel <sre@ring0.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* or any later version as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
#warning tint2 has no battery support for this operating system!
|
||||
|
||||
gboolean battery_os_init() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
return;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
return strdup("Operating System not supported");
|
||||
}
|
79
src/battery/freebsd.c
Normal file
79
src/battery/freebsd.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Tint2 : FreeBSD battery
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* or any later version as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
gboolean battery_os_init() {
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
|
||||
return (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
return;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
int sysctl_out = 0;
|
||||
size_t len = sizeof(sysctl_out);
|
||||
gboolean err = 0;
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) {
|
||||
switch(sysctl_out) {
|
||||
case 1:
|
||||
state->state = BATTERY_DISCHARGING;
|
||||
break;
|
||||
case 2:
|
||||
state->state = BATTERY_CHARGING;
|
||||
break;
|
||||
default:
|
||||
state->state = BATTERY_FULL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "power update: no such sysctl");
|
||||
err = -1;
|
||||
}
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0)
|
||||
batstate_set_time(state, sysctl_out * 60);
|
||||
else
|
||||
err = -1;
|
||||
|
||||
if (sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0)
|
||||
state->percentage = sysctl_out;
|
||||
else
|
||||
err = -1;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
return strdup("Operating System not supported");
|
||||
}
|
||||
|
||||
#endif
|
|
@ -24,6 +24,12 @@
|
|||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
enum psy_type {
|
||||
PSY_UNKNOWN,
|
||||
PSY_BATTERY,
|
||||
PSY_MAINS,
|
||||
};
|
||||
|
||||
struct psy_battery {
|
||||
/* generic properties */
|
||||
gchar* name;
|
||||
|
@ -44,11 +50,25 @@ struct psy_battery {
|
|||
enum chargestate status;
|
||||
};
|
||||
|
||||
struct psy_mains {
|
||||
/* generic properties */
|
||||
gchar* name;
|
||||
/* sysfs files */
|
||||
gchar* path_online;
|
||||
/* values */
|
||||
gboolean online;
|
||||
};
|
||||
|
||||
#define RETURN_ON_ERROR(err) if(error) { g_error_free(err); return FALSE; }
|
||||
|
||||
static GList *batteries = NULL;
|
||||
static GList *mains = NULL;
|
||||
|
||||
static gboolean power_supply_is_battery(const gchar *entryname) {
|
||||
static guint8 energy_to_percent(gint energy_now, gint energy_full) {
|
||||
return 0.5 + ((energy_now <= energy_full ? energy_now : energy_full) * 100.0) / energy_full;
|
||||
}
|
||||
|
||||
static enum psy_type power_supply_get_type(const gchar *entryname) {
|
||||
gchar *path_type = g_build_filename("/sys/class/power_supply", entryname, "type", NULL);
|
||||
GError *error = NULL;
|
||||
gchar *type;
|
||||
|
@ -56,16 +76,24 @@ static gboolean power_supply_is_battery(const gchar *entryname) {
|
|||
|
||||
g_file_get_contents(path_type, &type, &typelen, &error);
|
||||
g_free(path_type);
|
||||
RETURN_ON_ERROR(error);
|
||||
if (error) {
|
||||
g_error_free(error);
|
||||
return PSY_UNKNOWN;
|
||||
}
|
||||
|
||||
if(g_strcmp0(type, "Battery\n")) {
|
||||
if(!g_strcmp0(type, "Battery\n")) {
|
||||
g_free(type);
|
||||
return FALSE;
|
||||
return PSY_BATTERY;
|
||||
}
|
||||
|
||||
if(!g_strcmp0(type, "Mains\n")) {
|
||||
g_free(type);
|
||||
return PSY_MAINS;
|
||||
}
|
||||
|
||||
g_free(type);
|
||||
|
||||
return TRUE;
|
||||
return PSY_UNKNOWN;
|
||||
}
|
||||
|
||||
static gboolean init_linux_battery(struct psy_battery *bat) {
|
||||
|
@ -130,7 +158,19 @@ err0:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void free_linux_batteries() {
|
||||
static gboolean init_linux_mains(struct psy_mains *ac) {
|
||||
const gchar *entryname = ac->name;
|
||||
|
||||
ac->path_online = g_build_filename("/sys/class/power_supply", entryname, "online", NULL);
|
||||
if (!g_file_test(ac->path_online, G_FILE_TEST_EXISTS)) {
|
||||
g_free(ac->path_online);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
GList *l = batteries;
|
||||
|
||||
while (l != NULL) {
|
||||
|
@ -148,31 +188,70 @@ void free_linux_batteries() {
|
|||
l = next;
|
||||
}
|
||||
|
||||
l = mains;
|
||||
while (l != NULL) {
|
||||
GList *next = l->next;
|
||||
struct psy_mains *ac = l->data;
|
||||
|
||||
g_free(ac->name);
|
||||
g_free(ac->path_online);
|
||||
|
||||
mains = g_list_delete_link(mains, l);
|
||||
l = next;
|
||||
}
|
||||
|
||||
batteries = NULL;
|
||||
mains = NULL;
|
||||
}
|
||||
|
||||
gboolean init_linux_batteries() {
|
||||
static void add_battery(const char *entryname) {
|
||||
struct psy_battery *bat = g_malloc0(sizeof(*bat));
|
||||
bat->name = g_strdup(entryname);
|
||||
|
||||
if(init_linux_battery(bat)) {
|
||||
batteries = g_list_append(batteries, bat);
|
||||
fprintf(stdout, "found battery \"%s\"\n", bat->name);
|
||||
} else {
|
||||
g_free(bat);
|
||||
fprintf(stderr, RED "failed to initialize battery \"%s\"\n" RESET, entryname);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_mains(const char *entryname) {
|
||||
struct psy_mains *ac = g_malloc0(sizeof(*ac));
|
||||
ac->name = g_strdup(entryname);
|
||||
|
||||
if(init_linux_mains(ac)) {
|
||||
mains = g_list_append(mains, ac);
|
||||
fprintf(stdout, "found mains \"%s\"\n", ac->name);
|
||||
} else {
|
||||
g_free(ac);
|
||||
fprintf(stderr, RED "failed to initialize mains \"%s\"\n" RESET, entryname);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean battery_os_init() {
|
||||
GDir *directory = 0;
|
||||
GError *error = NULL;
|
||||
const char *entryname;
|
||||
|
||||
free_linux_batteries();
|
||||
battery_os_free();
|
||||
|
||||
directory = g_dir_open("/sys/class/power_supply", 0, &error);
|
||||
RETURN_ON_ERROR(error);
|
||||
|
||||
while ((entryname = g_dir_read_name(directory))) {
|
||||
if(!power_supply_is_battery(entryname))
|
||||
continue;
|
||||
enum psy_type type = power_supply_get_type(entryname);
|
||||
|
||||
struct psy_battery *bat = g_malloc0(sizeof(*bat));
|
||||
bat->name = g_strdup(entryname);
|
||||
if(init_linux_battery(bat)) {
|
||||
batteries = g_list_append(batteries, bat);
|
||||
fprintf(stdout, "found battery \"%s\"\n", bat->name);
|
||||
} else {
|
||||
g_free(bat);
|
||||
fprintf(stderr, RED "failed to initialize battery \"%s\"\n" RESET, entryname);
|
||||
switch(type) {
|
||||
case PSY_BATTERY:
|
||||
add_battery(entryname);
|
||||
break;
|
||||
case PSY_MAINS:
|
||||
add_mains(entryname);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,16 +316,34 @@ static gboolean update_linux_battery(struct psy_battery *bat) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void update_linux_batteries(enum chargestate *state, gint64 *energy_now, gint64 *energy_full, int *seconds) {
|
||||
|
||||
static gboolean update_linux_mains(struct psy_mains *ac) {
|
||||
GError *error = NULL;
|
||||
gchar *data;
|
||||
gsize datalen;
|
||||
ac->online = FALSE;
|
||||
|
||||
/* online */
|
||||
g_file_get_contents(ac->path_online, &data, &datalen, &error);
|
||||
RETURN_ON_ERROR(error);
|
||||
ac->online = (atoi(data) == 1);
|
||||
g_free(data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
GList *l;
|
||||
|
||||
gint64 total_energy_now = 0;
|
||||
gint64 total_energy_full = 0;
|
||||
gint64 total_power_now = 0;
|
||||
gint seconds = 0;
|
||||
|
||||
gboolean charging = FALSE;
|
||||
gboolean discharging = FALSE;
|
||||
gboolean full = FALSE;
|
||||
gboolean ac_connected = FALSE;
|
||||
|
||||
for (l = batteries; l != NULL; l = l->next) {
|
||||
struct psy_battery *bat = l->data;
|
||||
|
@ -261,27 +358,36 @@ void update_linux_batteries(enum chargestate *state, gint64 *energy_now, gint64
|
|||
full |= (bat->status == BATTERY_FULL);
|
||||
}
|
||||
|
||||
/* global energy stats */
|
||||
*energy_now = total_energy_now;
|
||||
*energy_full = total_energy_full;
|
||||
for (l = mains; l != NULL; l = l->next) {
|
||||
struct psy_mains *ac = l->data;
|
||||
update_linux_mains(ac);
|
||||
ac_connected |= (ac->online);
|
||||
}
|
||||
|
||||
/* build global state */
|
||||
*state = BATTERY_UNKNOWN;
|
||||
if (charging && !discharging)
|
||||
*state = BATTERY_CHARGING;
|
||||
state->state = BATTERY_CHARGING;
|
||||
else if (!charging && discharging)
|
||||
*state = BATTERY_DISCHARGING;
|
||||
state->state = BATTERY_DISCHARGING;
|
||||
else if (!charging && !discharging && full)
|
||||
*state = BATTERY_FULL;
|
||||
state->state = BATTERY_FULL;
|
||||
|
||||
/* calculate seconds */
|
||||
*seconds = 0;
|
||||
if (total_power_now > 0) {
|
||||
if(*state == BATTERY_CHARGING)
|
||||
*seconds = 3600 * (total_energy_full - total_energy_now) / total_power_now;
|
||||
else if(*state == BATTERY_DISCHARGING)
|
||||
*seconds = 3600 * total_energy_now / total_power_now;
|
||||
if(state->state == BATTERY_CHARGING)
|
||||
seconds = 3600 * (total_energy_full - total_energy_now) / total_power_now;
|
||||
else if(state->state == BATTERY_DISCHARGING)
|
||||
seconds = 3600 * total_energy_now / total_power_now;
|
||||
}
|
||||
batstate_set_time(state, seconds);
|
||||
|
||||
/* calculate percentage */
|
||||
state->percentage = energy_to_percent(total_energy_now, total_energy_full);
|
||||
|
||||
/* AC state */
|
||||
state->ac_connected = ac_connected;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gchar* energy_human_readable(struct psy_battery *bat) {
|
||||
|
@ -319,7 +425,7 @@ static gchar* power_human_readable(struct psy_battery *bat) {
|
|||
}
|
||||
}
|
||||
|
||||
const char* linux_batteries_get_tooltip() {
|
||||
char* battery_os_tooltip() {
|
||||
GList *l;
|
||||
GString *tooltip = g_string_new("");
|
||||
gchar *result;
|
||||
|
@ -341,7 +447,7 @@ const char* linux_batteries_get_tooltip() {
|
|||
gchar *energy = energy_human_readable(bat);
|
||||
gchar *state = (bat->status == BATTERY_UNKNOWN) ? "Level" : chargestate2str(bat->status);
|
||||
|
||||
guint percentage = 0.5 + ((bat->energy_now <= bat->energy_full ? bat->energy_now : bat->energy_full) * 100.0) / bat->energy_full;
|
||||
guint8 percentage = energy_to_percent(bat->energy_now, bat->energy_full);
|
||||
|
||||
g_string_append_printf(tooltip, "\t%s: %s (%u %%)\n\tPower: %s",
|
||||
state, energy, percentage, power);
|
||||
|
@ -350,6 +456,16 @@ const char* linux_batteries_get_tooltip() {
|
|||
g_free(energy);
|
||||
}
|
||||
|
||||
for (l = mains; l != NULL; l = l->next) {
|
||||
struct psy_mains *ac = l->data;
|
||||
|
||||
if (tooltip->len)
|
||||
g_string_append_c(tooltip, '\n');
|
||||
|
||||
g_string_append_printf(tooltip, "%s\n", ac->name);
|
||||
g_string_append_printf(tooltip, ac->online ? "\tconnected" : "\tdisconnected");
|
||||
}
|
||||
|
||||
result = tooltip->str;
|
||||
g_string_free(tooltip, FALSE);
|
||||
|
||||
|
|
84
src/battery/openbsd.c
Normal file
84
src/battery/openbsd.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Tint2 : OpenBSD & NetBSD battery
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* or any later version as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
|
||||
//#include <machine/apmvar.h>
|
||||
#include <err.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "battery.h"
|
||||
|
||||
int apm_fd = -1;
|
||||
|
||||
gboolean battery_os_init() {
|
||||
if (apm_fd > 0)
|
||||
close(apm_fd);
|
||||
|
||||
apm_fd = open("/dev/apm", O_RDONLY);
|
||||
|
||||
if (apm_fd < 0) {
|
||||
warn("ERROR: battery applet cannot open /dev/apm.");
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void battery_os_free() {
|
||||
if ((apm_fd != -1) && (close(apm_fd) == -1))
|
||||
warn("cannot close /dev/apm");
|
||||
apm_fd = -1;
|
||||
}
|
||||
|
||||
int battery_os_update(struct batstate *state) {
|
||||
struct apm_power_info info;
|
||||
|
||||
if (apm_fd > 0 && ioctl(apm_fd, APM_IOC_GETPOWER, &(info)) == 0) {
|
||||
// best attempt at mapping to Linux battery states
|
||||
switch (info.battery_state) {
|
||||
case APM_BATT_CHARGING:
|
||||
state->state = BATTERY_CHARGING;
|
||||
break;
|
||||
default:
|
||||
state->state = BATTERY_DISCHARGING;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.battery_life == 100)
|
||||
state->state = BATTERY_FULL;
|
||||
|
||||
if (info.minutes_left != -1)
|
||||
batstate_set_time(state, info.minutes_left * 60);
|
||||
|
||||
state->percentage = info.battery_life;
|
||||
} else {
|
||||
warn("power update: APM_IOC_GETPOWER");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* battery_os_tooltip() {
|
||||
return strdup("Operating System not supported");
|
||||
}
|
||||
|
||||
#endif
|
|
@ -48,7 +48,6 @@ PangoFontDescription *time1_font_desc;
|
|||
PangoFontDescription *time2_font_desc;
|
||||
static char buf_time[256];
|
||||
static char buf_date[256];
|
||||
static char buf_tooltip[512];
|
||||
int clock_enabled;
|
||||
static timeout* clock_timeout;
|
||||
|
||||
|
@ -144,10 +143,15 @@ struct tm* clock_gettime_for_tz(const char* timezone) {
|
|||
else return localtime(&time_clock.tv_sec);
|
||||
}
|
||||
|
||||
const char* clock_get_tooltip(void* obj)
|
||||
char* clock_get_tooltip(void* obj)
|
||||
{
|
||||
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
||||
return buf_tooltip;
|
||||
GTimeZone *tz = g_time_zone_new(time_tooltip_timezone);
|
||||
GDateTime *now = g_date_time_new_now(tz);
|
||||
char *result = g_date_time_format(now, time_tooltip_format);
|
||||
g_date_time_unref(now);
|
||||
g_time_zone_unref(tz);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int time_format_needs_sec_ticks(char *time_format)
|
||||
|
@ -197,7 +201,6 @@ void init_clock_panel(void *p)
|
|||
|
||||
if (time_tooltip_format) {
|
||||
clock->area._get_tooltip_text = clock_get_tooltip;
|
||||
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
src/config.c
12
src/config.c
|
@ -392,6 +392,18 @@ void add_entry (char *key, char *value)
|
|||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
battery_low_cmd = strdup (value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "ac_connected_cmd") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
ac_connected_cmd = strdup (value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "ac_disconnected_cmd") == 0) {
|
||||
#ifdef ENABLE_BATTERY
|
||||
if (strlen(value) > 0)
|
||||
ac_disconnected_cmd = strdup (value);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (key, "bat1_font") == 0) {
|
||||
|
|
|
@ -347,10 +347,10 @@ void launcher_icon_on_change_layout(void *obj)
|
|||
launcherIcon->area.height = launcherIcon->icon_size;
|
||||
}
|
||||
|
||||
const char* launcher_icon_get_tooltip_text(void *obj)
|
||||
char* launcher_icon_get_tooltip_text(void *obj)
|
||||
{
|
||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||
return launcherIcon->icon_tooltip;
|
||||
return strdup(launcherIcon->icon_tooltip);
|
||||
}
|
||||
|
||||
void draw_launcher_icon(void *obj, cairo_t *c)
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
timeout* urgent_timeout;
|
||||
GSList* urgent_list;
|
||||
|
||||
const char* task_get_tooltip(void* obj)
|
||||
char* task_get_tooltip(void* obj)
|
||||
{
|
||||
Task* t = obj;
|
||||
return t->title;
|
||||
return strdup(t->title);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ GtkWidget *battery_padding_x, *battery_padding_y, *battery_font_line1, *battery_
|
|||
GtkWidget *battery_background;
|
||||
GtkWidget *battery_tooltip;
|
||||
GtkWidget *battery_left_command, *battery_mclick_command, *battery_right_command, *battery_uwheel_command, *battery_dwheel_command;
|
||||
GtkWidget *ac_connected_cmd, *ac_disconnected_cmd;
|
||||
|
||||
// systray
|
||||
GtkWidget *systray_icon_order, *systray_padding_x, *systray_padding_y, *systray_spacing;
|
||||
|
@ -3817,6 +3818,50 @@ void create_battery(GtkWidget *parent)
|
|||
|
||||
change_paragraph(parent);
|
||||
|
||||
label = gtk_label_new(_("<b>AC connection events</b>"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(parent), label, FALSE, FALSE, 0);
|
||||
|
||||
table = gtk_table_new(2, 10, FALSE);
|
||||
gtk_widget_show(table);
|
||||
gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
|
||||
|
||||
row = 0, col = 2;
|
||||
label = gtk_label_new(_("AC connected command"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
|
||||
ac_connected_cmd = gtk_entry_new();
|
||||
gtk_widget_show(ac_connected_cmd);
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(ac_connected_cmd), 50);
|
||||
gtk_table_attach(GTK_TABLE(table), ac_connected_cmd, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
gtk_tooltips_set_tip(tooltips, ac_connected_cmd,
|
||||
_("Specifies a command that will be executed when AC is connected to the system."), NULL);
|
||||
|
||||
row++, col = 2;
|
||||
label = gtk_label_new(_("AC disconnected command"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
|
||||
ac_disconnected_cmd = gtk_entry_new();
|
||||
gtk_widget_show(ac_disconnected_cmd);
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(ac_disconnected_cmd), 50);
|
||||
gtk_table_attach(GTK_TABLE(table), ac_disconnected_cmd, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
gtk_tooltips_set_tip(tooltips, ac_disconnected_cmd,
|
||||
_("Specifies a command that will be executed when AC is disconnected to the system."), NULL);
|
||||
|
||||
change_paragraph(parent);
|
||||
|
||||
label = gtk_label_new(_("<b>Mouse events</b>"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
||||
|
|
|
@ -97,6 +97,7 @@ extern GtkWidget *battery_padding_x, *battery_padding_y, *battery_font_line1, *b
|
|||
extern GtkWidget *battery_background;
|
||||
extern GtkWidget *battery_tooltip;
|
||||
extern GtkWidget *battery_left_command, *battery_mclick_command, *battery_right_command, *battery_uwheel_command, *battery_dwheel_command;
|
||||
extern GtkWidget *ac_connected_cmd, *ac_disconnected_cmd;
|
||||
|
||||
// systray
|
||||
extern GtkWidget *systray_icon_order, *systray_padding_x, *systray_padding_y, *systray_spacing;
|
||||
|
|
|
@ -583,6 +583,9 @@ void config_write_battery(FILE *fp)
|
|||
fprintf(fp, "battery_uwheel_command = %s\n", gtk_entry_get_text(GTK_ENTRY(battery_uwheel_command)));
|
||||
fprintf(fp, "battery_dwheel_command = %s\n", gtk_entry_get_text(GTK_ENTRY(battery_dwheel_command)));
|
||||
|
||||
fprintf(fp, "ac_connected_cmd = %s\n", gtk_entry_get_text(GTK_ENTRY(ac_connected_cmd)));
|
||||
fprintf(fp, "ac_disconnected_cmd = %s\n", gtk_entry_get_text(GTK_ENTRY(ac_disconnected_cmd)));
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
|
@ -958,6 +961,12 @@ void add_entry(char *key, char *value)
|
|||
else if (strcmp(key, "battery_dwheel_command") == 0) {
|
||||
gtk_entry_set_text(GTK_ENTRY(battery_dwheel_command), value);
|
||||
}
|
||||
else if (strcmp(key, "ac_connected_cmd") == 0) {
|
||||
gtk_entry_set_text(GTK_ENTRY(ac_connected_cmd), value);
|
||||
}
|
||||
else if (strcmp(key, "ac_disconnected_cmd") == 0) {
|
||||
gtk_entry_set_text(GTK_ENTRY(ac_disconnected_cmd), value);
|
||||
}
|
||||
|
||||
/* Clock */
|
||||
else if (strcmp(key, "time1_format") == 0) {
|
||||
|
|
|
@ -304,7 +304,7 @@ void tooltip_copy_text(Area* area)
|
|||
{
|
||||
free(g_tooltip.tooltip_text);
|
||||
if (area && area->_get_tooltip_text)
|
||||
g_tooltip.tooltip_text = strdup(area->_get_tooltip_text(area));
|
||||
g_tooltip.tooltip_text = area->_get_tooltip_text(area);
|
||||
else
|
||||
g_tooltip.tooltip_text = NULL;
|
||||
g_tooltip.area = area;
|
||||
|
|
|
@ -91,7 +91,8 @@ typedef struct {
|
|||
// after pos/size changed, the rendering engine will call _on_change_layout(Area*)
|
||||
int on_changed;
|
||||
void (*_on_change_layout)(void *obj);
|
||||
const char* (*_get_tooltip_text)(void *obj);
|
||||
// returns allocated string, that must be free'd after usage
|
||||
char* (*_get_tooltip_text)(void *obj);
|
||||
} Area;
|
||||
|
||||
// on startup, initialize fixed pos/size
|
||||
|
|
Loading…
Reference in a new issue