static const char * apm_readinfo (BatteryStatus *status) { /* Code for Linux by Thomas Hood <*****@*****.**>. apm_read() will read from /proc/... instead and we do not need to open the device ourselves. */ if (DEBUG) g_print("apm_readinfo() (Linux)\n"); /* ACPI support added by Lennart Poettering <*****@*****.**> 10/27/2001 * Updated by David Moore <*****@*****.**> 5/29/2003 to poll less and * use ACPI events. */ if (using_acpi && acpiinfo.event_fd >= 0) { if (acpi_count <= 0) { /* Only call this one out of 30 calls to apm_readinfo() (every 30 seconds) * since reading the ACPI system takes CPU cycles. */ acpi_count=30; acpi_linux_read(&apminfo, &acpiinfo); } acpi_count--; } /* If we lost the file descriptor with ACPI events, try to get it back. */ else if (using_acpi) { if (acpi_linux_init(&acpiinfo)) { acpiwatch = g_io_add_watch (acpiinfo.channel, G_IO_IN | G_IO_ERR | G_IO_HUP, acpi_callback, NULL); acpi_linux_read(&apminfo, &acpiinfo); } } else apm_read(&apminfo); status->present = TRUE; status->on_ac_power = apminfo.ac_line_status ? 1 : 0; status->percent = (guint) apminfo.battery_percentage; status->charging = (apminfo.battery_flags & 0x8) ? TRUE : FALSE; status->minutes = apminfo.battery_time; return NULL; }
static gboolean acpi_callback (GIOChannel * chan, GIOCondition cond, gpointer data) { if (cond & (G_IO_ERR | G_IO_HUP)) { acpi_linux_cleanup(&acpiinfo); apminfo.battery_percentage = -1; return FALSE; } if (acpi_process_event(&acpiinfo)) { acpi_linux_read(&apminfo, &acpiinfo); } return TRUE; }
static gboolean update_apm_status(t_battmon *battmon) { #ifdef __OpenBSD__ struct apm_power_info apm; #else struct apm_info apm; #endif int charge; int time_remaining; gboolean acline; gchar buffer[128]; if(battmon->method == BM_BROKEN) { /* See if ACPI or APM support has been enabled yet */ if(!detect_battery_info(battmon)) return TRUE; if(battmon->timeoutid != 0) g_source_remove(battmon->timeoutid); /* Poll only once per minute if using ACPI due to a bug */ if(battmon->method == BM_USE_ACPI) { battmon->timeoutid = g_timeout_add(60 * 1000, (GSourceFunc) update_apm_status, battmon); } else { battmon->timeoutid = g_timeout_add(2 * 1000, (GSourceFunc) update_apm_status, battmon); } } /* Show initial state if using ACPI rather than waiting a minute */ if(battmon->flag) { battmon->flag = FALSE; g_source_remove(battmon->timeoutid); battmon->timeoutid = g_timeout_add(60 * 1000, (GSourceFunc) update_apm_status, battmon); } #ifdef __FreeBSD__ /* This is how I read the information from the APM subsystem under FreeBSD. Each time this functions is called (once every second) the APM device is opened, read from and then closed. */ int fd; battmon->method = BM_BROKEN; fd = open(APMDEVICE, O_RDONLY); if (fd == -1) return TRUE; if (ioctl(fd, APMIO_GETINFO, &apm) == -1) return TRUE; close(fd); acline = apm.ai_acline ? TRUE : FALSE; time_remaining = apm.ai_batt_time; time_remaining = time_remaining / 60; /* convert from seconds to minutes */ charge = apm.ai_batt_life; #elif __OpenBSD__ /* Code for OpenBSD by Joe Ammond <*****@*****.**>. Using the same procedure as for FreeBSD. */ int fd; battmon->method = BM_BROKEN; fd = open(APMDEVICE, O_RDONLY); if (fd == -1) return TRUE; if (ioctl(fd, APM_IOC_GETPOWER, &apminfo) == -1) return TRUE; close(fd); charge = apm.battery_life; time_remaining = apm.minutes_left; acline = apm.ac_state ? TRUE : FALSE; #elif __linux__ if(battmon->method == BM_USE_ACPI) acpi_linux_read(&apm); else apm_read(&apm); /* not broken and not using ACPI, assume APM */ charge = apm.battery_percentage; if(battmon->method == BM_USE_ACPI) time_remaining = 0; /* no such info for ACPI :( */ else time_remaining = apm.battery_time; acline = apm.ac_line_status ? TRUE : FALSE; #endif if(charge < 0) charge = 0; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(battmon->battstatus), charge / 100.0); if(battmon->options.tooltip_display_percentage && battmon->options.tooltip_display_time) { if(acline) g_snprintf(buffer, sizeof(buffer), _("%d%% (AC on-line)"), charge); else if(time_remaining > 0) g_snprintf(buffer, sizeof(buffer), _("%d%% (%d:%.2d) remaining"), charge, time_remaining / 60, time_remaining % 60); else g_snprintf(buffer, sizeof(buffer), _("%d%% (AC off-line)"), charge); add_tooltip(battmon->ebox, buffer); } else if(battmon->options.tooltip_display_percentage) { g_snprintf(buffer, sizeof(buffer), _("%d%%"), charge); add_tooltip(battmon->ebox, buffer); } else if(battmon->options.tooltip_display_time) { if(acline) g_snprintf(buffer, sizeof(buffer), _("AC on-line")); else if(time_remaining > 0) g_snprintf(buffer, sizeof(buffer), _("%d:%.2d remaining"), time_remaining / 60, time_remaining % 60); else g_snprintf(buffer, sizeof(buffer), _("AC off-line")); add_tooltip(battmon->ebox, buffer); } else add_tooltip(battmon->ebox, NULL); if(battmon->options.display_percentage) { g_snprintf(buffer, sizeof(buffer), _("%d%%"), charge); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(battmon->battstatus), buffer); } else gtk_progress_bar_set_text(GTK_PROGRESS_BAR(battmon->battstatus), NULL); if(!battmon->critical && charge <= battmon->options.critical_percentage) { battmon->critical = TRUE; battmon->low = TRUE; if(battmon->options.action_on_critical == BM_MESSAGE) xfce_warn(_("WARNING: Your battery has reached critical status. You should plug in or shutdown your computer now to avoid possible data loss.")); if(battmon->options.action_on_critical == BM_COMMAND) { if(battmon->options.command_on_critical && battmon->options.command_on_critical[0]) exec_cmd(battmon->options.command_on_critical, 0, 0); } if(battmon->options.action_on_critical == BM_COMMAND_TERM) { if(battmon->options.command_on_critical && battmon->options.command_on_critical[0]) exec_cmd(battmon->options.command_on_critical, 1, 0); } } else if(battmon->critical && charge > battmon->options.critical_percentage) battmon->critical = FALSE; if(!battmon->low && charge <= battmon->options.low_percentage) { battmon->low = TRUE; if(battmon->options.action_on_low == BM_MESSAGE) xfce_warn(_("WARNING: Your battery is running low. You should consider plugging in or shutting down your computer soon to avoid possible data loss.")); if(battmon->options.action_on_low == BM_COMMAND) { if(battmon->options.command_on_low && battmon->options.command_on_low[0]) exec_cmd(battmon->options.command_on_low, 0, 0); } if(battmon->options.action_on_low == BM_COMMAND_TERM) { if(battmon->options.command_on_low && battmon->options.command_on_low[0]) exec_cmd(battmon->options.command_on_low, 1, 0); } } else if(battmon->low && charge > battmon->options.low_percentage) battmon->low = FALSE; return TRUE; }
gboolean detect_battery_info(t_battmon *battmon) { #ifdef __OpenBSD__ struct apm_power_info apm; #else struct apm_info apm; #endif #ifdef __FreeBSD__ /* This is how I read the information from the APM subsystem under FreeBSD. Each time this functions is called (once every second) the APM device is opened, read from and then closed. */ int fd; battmon->method = BM_BROKEN; fd = open(APMDEVICE, O_RDONLY); if (fd == -1) return FALSE; if (ioctl(fd, APMIO_GETINFO, &apm) == -1) return FALSE; close(fd); battmon->method = BM_USE_APM; return TRUE; #elif __OpenBSD__ /* Code for OpenBSD by Joe Ammond <*****@*****.**>. Using the same procedure as for FreeBSD. */ int fd; battmon->method = BM_BROKEN; fd = open(APMDEVICE, O_RDONLY); if (fd == -1) return FALSE; if (ioctl(fd, APM_IOC_GETPOWER, &apm) == -1) return FALSE; close(fd); battmon->method = BM_USE_APM; return TRUE; #elif __linux__ /* First check to see if ACPI is available */ if(acpi_linux_read(&apm)) { /* ACPI detected and working */ battmon->method = BM_USE_ACPI; return TRUE; } if(apm_read(&apm) == 0) { /* ACPI not detected, but APM works */ battmon->method = BM_USE_APM; return TRUE; } /* Neither ACPI or APM detected/working */ battmon->method = BM_BROKEN; return FALSE; #endif }