$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 #include #include +#ifdef __OpenBSD__ +#include +#else #include +#endif #include #include #include #include #include #include +#ifdef __OpenBSD__ +#include +#include +#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: */