Files
archived-lcd4linux/plugin_apm.c
reinelt 1a6167b7b7 [lcd4linux @ 2004-03-14 07:11:42 by reinelt]
parameter count fixed for plugin_dvb()
plugin_APM (battery status) ported

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@401 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
2004-03-14 07:11:42 +00:00

197 lines
4.6 KiB
C

/* $Id: plugin_apm.c,v 1.1 2004/03/14 07:11:42 reinelt Exp $
*
* plugin for APM (battery status)
*
* Copyright 2003 Michael Reinelt <reinelt@eunet.at>
* Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
*
* based on the old 'battery.c' which is
* Copyright 2001 Leopold Tötsch <lt@toetsch.at>
*
* This file is part of LCD4Linux.
*
* LCD4Linux is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* $Log: plugin_apm.c,v $
* Revision 1.1 2004/03/14 07:11:42 reinelt
* parameter count fixed for plugin_dvb()
* plugin_APM (battery status) ported
*
*/
/*
* exported functions:
*
* int plugin_init_apm (void)
* adds apm() function
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <asm/types.h>
#include "debug.h"
#include "plugin.h"
#include "hash.h"
static int fd = -2;
static HASH APM = { 0, };
/* from /usr/src/linux/arch/i386/kernel/apm.c:
*
* Arguments, with symbols from linux/apm_bios.h. Information is
* from the Get Power Status (0x0a) call unless otherwise noted.
*
* 0) Linux driver version (this will change if format changes)
* 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
* 2) APM flags from APM Installation Check (0x00):
* bit 0: APM_16_BIT_SUPPORT
* bit 1: APM_32_BIT_SUPPORT
* bit 2: APM_IDLE_SLOWS_CLOCK
* bit 3: APM_BIOS_DISABLED
* bit 4: APM_BIOS_DISENGAGED
* 3) AC line status
* 0x00: Off-line
* 0x01: On-line
* 0x02: On backup power (BIOS >= 1.1 only)
* 0xff: Unknown
* 4) Battery status
* 0x00: High
* 0x01: Low
* 0x02: Critical
* 0x03: Charging
* 0x04: Selected battery not present (BIOS >= 1.2 only)
* 0xff: Unknown
* 5) Battery flag
* bit 0: High
* bit 1: Low
* bit 2: Critical
* bit 3: Charging
* bit 7: No system battery
* 0xff: Unknown
* 6) Remaining battery life (percentage of charge):
* 0-100: valid
* -1: Unknown
* 7) Remaining battery life (time units):
* Number of remaining minutes or seconds
* -1: Unknown
* 8) min = minutes; sec = seconds
*
* p+= sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
* driver_version,
* (apm_info.bios.version >> 8) & 0xff,
* apm_info.bios.version & 0xff,
* apm_info.bios.flags,
* ac_line_status,
* battery_status,
* battery_flag,
* percentage,
* time_units,
* units);
*/
static int parse_proc_apm (void)
{
char *key[] = { "driver_version",
"bios_version",
"bios_flags",
"line_status",
"battery_status",
"battery_flag",
"battery_percent",
"battery_remaining",
"time_units" };
char buffer[128], *beg, *end;
int age, i;
// reread every 10 msec only
age = hash_age (&APM, NULL, NULL);
if (age > 0 && age <= 10) return 0;
if (fd == -2) {
fd = open("/proc/apm", O_RDONLY | O_NDELAY);
if (fd == -1) {
error ("open(/proc/apm) failed: %s", strerror(errno));
return -1;
}
}
if (lseek(fd, 0L, SEEK_SET) != 0) {
error ("lseek(/proc/apm) failed: %s", strerror(errno));
fd = -1;
return -1;
}
if (read (fd, &buffer, sizeof(buffer)-1) == -1) {
error ("read(/proc/apm) failed: %s", strerror(errno));
fd=-1;
return -1;
}
beg = buffer;
for (i = 0; i < 9 && beg != NULL; i++) {
while (*beg == ' ') beg++;
if ((end = strpbrk(beg, " \n"))) *end='\0';
hash_set (&APM, key[i], beg);
beg = end ? end+1 : NULL;
}
return 0;
}
static void my_apm (RESULT *result, RESULT *arg1)
{
char *val;
if (parse_proc_apm()<0) {
SetResult(&result, R_STRING, "");
return;
}
val=hash_get(&APM, R2S(arg1));
if (val==NULL) val="";
SetResult(&result, R_STRING, val);
}
int plugin_init_apm (void)
{
AddFunction ("apm", 1, my_apm);
return 0;
}
void plugin_exit_apm (void)
{
if (fd > -1) {
close (fd);
}
fd = -2;
hash_destroy(&APM);
}