openbsd-ports/sysutils/tpb/patches/patch-src_tpb_c
jcs cb9da7a10f when the laptop volume is muted, it's kind of hard to notice the
little flashing battery icon when the battery is about to die

so as long as we're talking to /dev/apm, store the battery level and
show when it changes ("Battery level changed to low")
2007-06-01 16:44:10 +00:00

216 lines
6.4 KiB
Plaintext

$OpenBSD: patch-src_tpb_c,v 1.4 2007/06/01 16:44:11 jcs Exp $
--- src/tpb.c.orig Mon Jul 18 08:15:59 2005
+++ src/tpb.c Fri Jun 1 10:34:14 2007
@@ -25,13 +25,21 @@
#include <sys/wait.h>
#include <locale.h>
#include <signal.h>
+#ifdef __OpenBSD__
+#include <soundcard.h>
+#else
#include <sys/soundcard.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef __OpenBSD__
+#include <sys/ioctl.h>
+#include <machine/apmvar.h>
+#endif
#include "config.h"
#if ENABLE_NLS
@@ -84,8 +92,13 @@ int apmiser_running(void);
int *xerrorhandler(Display *display, XErrorEvent *event);
#endif /* HAVE_LIBX11 */
void sig_chld_handler(int signo);
+#ifdef __OpenBSD__
+const char *apm_battery_level(int state);
+#endif
/* }}} */
+int nfd = -1;
+
int main(int argc, char **argv) /* {{{ */
{
t_thinkpad_state thinkpad_state, last_thinkpad_state;
@@ -103,6 +116,17 @@ int main(int argc, char **argv) /* {{{ */
Display *display = NULL;
#endif /* HAVE_LIBX11 */
+ /* open nvram */
+ if ((nfd = open(PATH_NVRAM, O_RDONLY|O_NONBLOCK, 0)) < 0) {
+ fprintf(stderr, _("Unable to open device %s: "), PATH_NVRAM);
+ perror(NULL);
+ return -1;
+ }
+
+ /* drop privileges */
+ setegid(getgid());
+ setgid(getgid());
+
/* zero thinkpad_state */
memset(&thinkpad_state, 0, sizeof(thinkpad_state));
@@ -143,7 +167,7 @@ int main(int argc, char **argv) /* {{{ */
/* become a daemon if requested */
if(cfg.daemon == STATE_ON) {
- daemonize();
+ daemon(0, 0);
}
/* initialize osd */
@@ -638,6 +662,28 @@ int main(int argc, char **argv) /* {{{ */
#endif /* HAVE_LIBXOSD */
} /* }}} */
+#ifdef __OpenBSD__
+ /* determine the level of battery {{{ */
+ if(thinkpad_state.battery_level != last_thinkpad_state.battery_level) {
+ if(cfg.verbose == STATE_ON) {
+ printf(_("Battery level changed: %s\n"), _(apm_battery_level(thinkpad_state.battery_level)));
+ }
+ if(cfg.callback != NULL) {
+ snprintf(callback_cmd, sizeof(callback_cmd), "%s battery_level %s", cfg.callback, _(apm_battery_level(thinkpad_state.battery_level)));
+ if(fork_app(callback_cmd) != 0) {
+ _exit(0);
+ }
+ }
+#ifdef HAVE_LIBXOSD
+ if(osd_ptr != NULL &&
+ ((cfg.osd == STATE_OFF && cfg.osdpowermgt == STATE_ON) || (cfg.osd == STATE_ON && cfg.osdpowermgt != STATE_OFF))) {
+ xosd_display(osd_ptr, 0, XOSD_printf, "Battery level changed to %s", apm_battery_level(thinkpad_state.battery_level));
+ xosd_display(osd_ptr, 1, XOSD_string, "");
+ }
+#endif /* HAVE_LIBXOSD */
+ } /* }}} */
+#endif
+
/* determine power management mode AC {{{ */
if(thinkpad_state.powermgt_ac != last_thinkpad_state.powermgt_ac) {
switch(thinkpad_state.powermgt_ac) {
@@ -980,7 +1026,6 @@ Display *init_xgrabkey(void) /* {{{ */
/* get the current state from the nvram */
int get_nvram_state(t_thinkpad_state *thinkpad_state) /* {{{ */
{
- static int fdsc = -1; /* -1 -> file not opened */
unsigned char buffer[114];
struct {
int pos;
@@ -994,26 +1039,20 @@ int get_nvram_state(t_thinkpad_state *thinkpad_state)
};
int pos_len_idx = 0;
- /* open nvram for reading */
- if(fdsc == -1) { /* if not already opened, open nvram */
- if((fdsc=open(cfg.nvram, O_RDONLY|O_NONBLOCK)) == -1) {
- fprintf(stderr, _("Unable to open device %s: "), cfg.nvram);
- perror(NULL);
- return -1;
- }
- }
+ if (nfd < 0)
+ return -1;
/* Read only the interesting bytes from nvram to reduce the CPU consupmtion of tpb */
/* The kernel nvram driver reads byte-by-byte from nvram, so just reading interesting bytes reduces the amount of inb() calls */
while (pos_len[pos_len_idx].pos != 0x0) {
- if(lseek(fdsc, pos_len[pos_len_idx].pos, SEEK_SET) != pos_len[pos_len_idx].pos ) {
- fprintf(stderr, _("Unable to seek in device %s: "), cfg.nvram);
+ if(lseek(nfd, pos_len[pos_len_idx].pos, SEEK_SET) != pos_len[pos_len_idx].pos ) {
+ fprintf(stderr, _("Unable to seek in device %s: "), PATH_NVRAM);
perror(NULL);
return -1;
}
- if(read(fdsc, buffer+pos_len[pos_len_idx].pos, pos_len[pos_len_idx].len) != pos_len[pos_len_idx].len) {
+ if(read(nfd, buffer+pos_len[pos_len_idx].pos, pos_len[pos_len_idx].len) != pos_len[pos_len_idx].len) {
- fprintf(stderr, _("Unable to read from device %s: "), cfg.nvram);
+ fprintf(stderr, _("Unable to read from device %s: "), PATH_NVRAM);
perror(NULL);
return -1;
}
@@ -1045,11 +1084,28 @@ int get_nvram_state(t_thinkpad_state *thinkpad_state)
/* get the current state from the apm subsystem */
int get_apm_state(t_thinkpad_state *thinkpad_state) /* {{{ */
{
- unsigned int i;
static int fdsc = -1; /* -1 -> file not opened */
+#ifdef __OpenBSD__
+ struct apm_power_info info;
+#else
+ unsigned int i;
char buffer[38];
char *tokens[9];
+#endif
+#ifdef __OpenBSD__
+ memset(&info, 0, sizeof(info));
+
+ if (fdsc == -1)
+ fdsc = open("/dev/apm", O_RDONLY);
+
+ if (fdsc) {
+ if (ioctl(fdsc, APM_IOC_GETPOWER, &info) == 0) {
+ thinkpad_state->ac_state = (info.ac_state ? STATE_ON : STATE_OFF);
+ thinkpad_state->battery_level = info.battery_state;
+ }
+ }
+#else
/* Read the state of the ac line from proc filesystem.
* Documentation of /proc/apm from linux kernel (/usr/src/linux/arch/i386/kernel/apm.c)
*
@@ -1122,6 +1178,7 @@ int get_apm_state(t_thinkpad_state *thinkpad_state) /*
thinkpad_state->ac_state = STATE_ON;
break;
}
+#endif
return 0;
} /* }}} */
@@ -1283,6 +1340,11 @@ void set_nvram_volume_level(t_thinkpad_state *thinkpad
int fdsc;
char buffer;
+#ifdef __OpenBSD__
+ /* nvram writing not supported in OpenBSD */
+ return;
+#endif
+
/* only use writeback to nvram when cfg.mixersteps is different from DEFAULT_MIXERSTEPS */
if(cfg.mixersteps != DEFAULT_MIXERSTEPS) {
/* open nvram */
@@ -1466,5 +1528,28 @@ void sig_chld_handler(int signo) /* {{{ */
waitpid(-1, &status, WNOHANG);
return;
} /* }}} */
+
+#ifdef __OpenBSD__
+const char *
+apm_battery_level(int state)
+{
+ switch (state) {
+ case APM_BATT_HIGH:
+ return "high";
+ case APM_BATT_LOW:
+ return "low";
+ case APM_BATT_CRITICAL:
+ return "CRITICAL";
+ case APM_BATT_CHARGING:
+ return "charging";
+ case APM_BATTERY_ABSENT:
+ return "absent";
+ case APM_BATT_UNKNOWN:
+ return "unknown";
+ default:
+ return "invalid battery state";
+ }
+}
+#endif
/* vim600:set fen:set fdm=marker:set fdl=0: */