diff options
author | marcus <marcus@FreeBSD.org> | 2005-06-29 13:09:44 +0800 |
---|---|---|
committer | marcus <marcus@FreeBSD.org> | 2005-06-29 13:09:44 +0800 |
commit | c4900ad194a670f23f56a4904dc93960e53ed311 (patch) | |
tree | 883554f6f89fa4ecd05fb36af22def022d4705c1 /x11/gnome-applets | |
parent | 79634ce5a95d1c54ac08cc7fa16abb3764be88b9 (diff) | |
download | freebsd-ports-gnome-c4900ad194a670f23f56a4904dc93960e53ed311.tar.gz freebsd-ports-gnome-c4900ad194a670f23f56a4904dc93960e53ed311.tar.zst freebsd-ports-gnome-c4900ad194a670f23f56a4904dc93960e53ed311.zip |
Add support for getting real-time acpi battery events from devd. This
won't work yet for non-root users unless they are using my devd patch
at http://www.marcuscom.com/downloads/devd.diff to give open permissions
to the devd.pipe socket.
Without this real-time update support, it can take up to 30 seconds for the
battstat applet to update on an ACPI event. Because this support is still
experimental, I am not bumping PORTREVISION.
Diffstat (limited to 'x11/gnome-applets')
-rw-r--r-- | x11/gnome-applets/files/patch-battstat-acpi | 269 |
1 files changed, 185 insertions, 84 deletions
diff --git a/x11/gnome-applets/files/patch-battstat-acpi b/x11/gnome-applets/files/patch-battstat-acpi index a3b505291e8f..09f34d9fbd8f 100644 --- a/x11/gnome-applets/files/patch-battstat-acpi +++ b/x11/gnome-applets/files/patch-battstat-acpi @@ -1,62 +1,3 @@ ---- battstat/acpi-freebsd.h.orig Mon Sep 27 18:39:30 2004 -+++ battstat/acpi-freebsd.h Mon Sep 27 18:39:30 2004 -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (C) 2004 by Joe Marcus Clarke <marcus@FreeBSD.org> -+ * -+ * This program 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 of the License, or -+ * (at your option) any later version. -+ * -+ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA. -+ */ -+ -+#ifndef __ACPI_FREEBSD_H__ -+#define __ACPI_FREEBSD_H__ -+ -+#define ACPIDEV "/dev/acpi" -+ -+#define BATT_MIN 0 -+#define BATT_MAX 64 -+ -+#define ACPI_ACLINE "hw.acpi.acline" -+#define ACPI_TIME "hw.acpi.battery.time" -+#define ACPI_LIFE "hw.acpi.battery.life" -+#define ACPI_STATE "hw.acpi.battery.state" -+ -+/* XXX: AMD64 does not have machine/apm_bios.h. */ -+#if !defined(__i386__) -+struct apm_info { -+ guint ai_acline; -+ guint ai_batt_stat; -+ guint ai_batt_life; -+ int ai_batt_time; -+ guint ai_status; -+}; -+#endif -+ -+struct acpi_info { -+ gboolean ac_online; -+ int acpifd; -+ int max_capacity; -+ int low_capacity; -+ int critical_capacity; -+}; -+ -+gboolean acpi_freebsd_read(struct apm_info *apminfo, struct acpi_info * acpiinfo); -+gboolean acpi_process_event(struct acpi_info * acpiinfo); -+gboolean acpi_freebsd_init(struct acpi_info * acpiinfo); -+void acpi_freebsd_cleanup(struct acpi_info * acpiinfo); -+ -+#endif /* __ACPI_FREEBSD_H__ */ --- battstat/Makefile.in.orig Mon Jan 24 20:20:49 2005 +++ battstat/Makefile.in Mon Jan 24 20:22:02 2005 @@ -55,9 +55,10 @@ @@ -137,9 +78,9 @@ #include "battstat.h" #ifndef gettext_noop ---- battstat/acpi-freebsd.c.orig Mon Feb 28 01:41:08 2005 -+++ battstat/acpi-freebsd.c Mon Feb 28 03:00:11 2005 -@@ -0,0 +1,208 @@ +--- battstat/acpi-freebsd.c.orig Tue Jun 28 23:40:48 2005 ++++ battstat/acpi-freebsd.c Wed Jun 29 00:54:12 2005 +@@ -0,0 +1,265 @@ +/* battstat A GNOME battery meter for laptops. + * Copyright (C) 2000 by Jörgen Pehrson <jp@spektr.eu.org> + * @@ -173,7 +114,9 @@ + +#include <stdio.h> +#include <sys/types.h> ++#include <sys/socket.h> +#include <sys/sysctl.h> ++#include <sys/un.h> +#include <sys/ioctl.h> +#if defined(__i386__) +#include <machine/apm_bios.h> @@ -234,6 +177,7 @@ +acpi_freebsd_init(struct acpi_info * acpiinfo) +{ + int acpi_fd; ++ int event_fd; + + g_assert(acpiinfo); + @@ -246,12 +190,75 @@ + return FALSE; + } + ++ event_fd = socket(PF_UNIX, SOCK_STREAM, 0); ++ if (event_fd >= 0) { ++ struct sockaddr_un addr; ++ addr.sun_family = AF_UNIX; ++ strcpy(addr.sun_path, "/var/run/devd.pipe"); ++ if (connect(event_fd, (struct sockaddr *) &addr, sizeof(addr)) == 0) { ++ acpiinfo->event_fd = event_fd; ++ acpiinfo->channel = g_io_channel_unix_new(event_fd); ++ } ++ else { ++ close(event_fd); ++ acpiinfo->event_fd = -1; ++ } ++ } ++ + update_battery_info(acpiinfo); + update_ac_info(acpiinfo); + + return TRUE; +} + ++#define ACPI_EVENT_IGNORE 0 ++#define ACPI_EVENT_AC 1 ++#define ACPI_EVENT_BATTERY_INFO 2 ++ ++static int parse_acpi_event(GString *buffer) ++{ ++ if (strstr(buffer->str, "system=ACPI")) { ++ if (strstr(buffer->str, "subsystem=ACAD")) ++ return ACPI_EVENT_AC; ++ if (strstr(buffer->str, "subsystem=CMBAT")) ++ return ACPI_EVENT_BATTERY_INFO; ++ } ++ ++ return ACPI_EVENT_IGNORE; ++} ++ ++gboolean acpi_process_event(struct acpi_info *acpiinfo, gboolean *read_error) ++{ ++ gsize i; ++ int evt; ++ gboolean result = FALSE; ++ GString *buffer; ++ GError *gerror = NULL; ++ GIOStatus stat; ++ buffer = g_string_new(NULL); ++ ++ stat = g_io_channel_read_line_string(acpiinfo->channel, buffer, &i, &gerror); ++ ++ if (stat = G_IO_STATUS_ERROR || stat == G_IO_STATUS_EOF) { ++ *read_error = TRUE; ++ return FALSE; ++ } ++ ++ evt = parse_acpi_event(buffer); ++ switch (evt) { ++ case ACPI_EVENT_AC: ++ update_ac_info(acpiinfo); ++ result = TRUE; ++ break; ++ case ACPI_EVENT_BATTERY_INFO: ++ update_battery_info(acpiinfo); ++ result = TRUE; ++ break; ++ } ++ ++ return result; ++} ++ +void +acpi_freebsd_cleanup(struct acpi_info * acpiinfo) +{ @@ -261,21 +268,12 @@ + close(acpiinfo->acpifd); + acpiinfo->acpifd = -1; + } -+} -+ -+/* XXX This is a hack since user-land applications can't get ACPI events yet. -+ * Devd provides this (or supposedly provides this), but you need to be -+ * root to access devd. -+ */ -+gboolean -+acpi_process_event(struct acpi_info * acpiinfo) -+{ -+ g_assert(acpiinfo); -+ -+ update_ac_info(acpiinfo); -+ update_battery_info(acpiinfo); + -+ return TRUE; ++ if (acpiinfo->event_fd >= 0) { ++ g_io_channel_unref(acpiinfo->channel); ++ close(acpiinfo->event_fd); ++ acpiinfo->event_fd = -1; ++ } +} + +gboolean @@ -348,9 +346,70 @@ + return TRUE; +} +#endif +--- battstat/acpi-freebsd.h.orig Tue Jun 28 23:40:48 2005 ++++ battstat/acpi-freebsd.h Wed Jun 29 00:53:36 2005 +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (C) 2004 by Joe Marcus Clarke <marcus@FreeBSD.org> ++ * ++ * This program 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 of the License, or ++ * (at your option) any later version. ++ * ++ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA. ++ */ ++ ++#ifndef __ACPI_FREEBSD_H__ ++#define __ACPI_FREEBSD_H__ ++ ++#define ACPIDEV "/dev/acpi" ++ ++#define BATT_MIN 0 ++#define BATT_MAX 64 ++ ++#define ACPI_ACLINE "hw.acpi.acline" ++#define ACPI_TIME "hw.acpi.battery.time" ++#define ACPI_LIFE "hw.acpi.battery.life" ++#define ACPI_STATE "hw.acpi.battery.state" ++ ++/* XXX: AMD64 does not have machine/apm_bios.h. */ ++#if !defined(__i386__) ++struct apm_info { ++ guint ai_acline; ++ guint ai_batt_stat; ++ guint ai_batt_life; ++ int ai_batt_time; ++ guint ai_status; ++}; ++#endif ++ ++struct acpi_info { ++ gboolean ac_online; ++ int acpifd; ++ int event_fd; ++ int max_capacity; ++ int low_capacity; ++ int critical_capacity; ++ GIOChannel * channel; ++}; ++ ++gboolean acpi_freebsd_read(struct apm_info *apminfo, struct acpi_info * acpiinfo); ++gboolean acpi_process_event(struct acpi_info * acpiinfo, gboolean *read_error); ++gboolean acpi_freebsd_init(struct acpi_info * acpiinfo); ++void acpi_freebsd_cleanup(struct acpi_info * acpiinfo); ++ ++#endif /* __ACPI_FREEBSD_H__ */ --- battstat/power-management.c.orig Sun Mar 20 05:20:55 2005 -+++ battstat/power-management.c Thu Jun 9 21:56:14 2005 -@@ -73,9 +73,18 @@ static int pm_initialised; ++++ battstat/power-management.c Wed Jun 29 00:53:05 2005 +@@ -73,12 +73,44 @@ static int pm_initialised; * the problem might be. This error message is not to be freed. */ @@ -365,13 +424,39 @@ +static struct acpi_info acpiinfo; +static gboolean using_acpi; +static int acpi_count; ++static int acpiwatch; +static struct apm_info apminfo; + +gboolean acpi_freebsd_read(struct apm_info *apminfo, struct acpi_info *acpiinfo); #define APMDEVICE "/dev/apm" -@@ -86,32 +95,46 @@ apm_readinfo (BatteryStatus *status) ++static gboolean acpi_callback (GIOChannel * chan, GIOCondition cond, gpointer data) ++{ ++ gboolean read_error; ++ ++ if (cond & (G_IO_ERR | G_IO_HUP)) { ++ acpi_freebsd_cleanup(&acpiinfo); ++ apminfo.ai_batt_life = -1; ++ return FALSE; ++ } ++ ++ if (acpi_process_event(&acpiinfo, &read_error)) { ++ acpi_freebsd_read(&apminfo, &acpiinfo); ++ } ++ else if (read_error) { ++ acpi_freebsd_cleanup(&acpiinfo); ++ apminfo.ai_batt_life = -1; ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + static const char * + apm_readinfo (BatteryStatus *status) + { +@@ -86,32 +118,53 @@ apm_readinfo (BatteryStatus *status) FreeBSD. Each time this functions is called (once every second) the APM device is opened, read from and then closed. */ @@ -385,14 +470,21 @@ - { - pm_initialised = 0; - return ERR_OPEN_APMDEV; -+ if (using_acpi) { ++ if (using_acpi && acpiinfo.event_fd >= 0) { + if (acpi_count <= 0) { -+ acpi_count = 3; -+ acpi_process_event(&acpiinfo); ++ acpi_count = 30; + acpi_freebsd_read(&apminfo, &acpiinfo); + } + acpi_count--; } ++ else if (using_acpi) { ++ if (acpi_freebsd_init(&acpiinfo)) { ++ acpiwatch = g_io_add_watch (acpiinfo.channel, ++ G_IO_IN | G_IO_ERR | G_IO_HUP, ++ acpi_callback, NULL); ++ acpi_freebsd_read(&apminfo, &acpiinfo); ++ } ++ } + else { +#if defined(__i386__) + fd = open(APMDEVICE, O_RDONLY); @@ -430,7 +522,7 @@ return NULL; } -@@ -339,6 +362,13 @@ power_management_initialise( void ) +@@ -339,6 +392,19 @@ power_management_initialise( void ) G_IO_IN | G_IO_ERR | G_IO_HUP, acpi_callback, NULL); } @@ -441,16 +533,25 @@ + } + else + using_acpi = FALSE; ++ ++ if (using_acpi && acpiinfo.event_fd >= 0) { ++ acpiwatch = g_io_add_watch (acpiinfo.channel, ++ G_IO_IN | G_IO_ERR | G_IO_HUP, ++ acpi_callback, NULL); ++ } #endif pm_initialised = 1; -@@ -360,6 +390,10 @@ power_management_cleanup( void ) +@@ -360,6 +426,13 @@ power_management_cleanup( void ) g_source_remove(acpiwatch); acpiwatch = 0; acpi_linux_cleanup(&acpiinfo); + } +#elif defined(__FreeBSD__) + if (using_acpi) { ++ if (acpiwatch != 0) ++ g_source_remove(acpiwatch); ++ acpiwatch = 0; + acpi_freebsd_cleanup(&acpiinfo); } #endif |