/*
* Copyright (C) 2005 Alex Murray <pragmatine@gmail.com>
*
* 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 Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "sensors-applet.h"
#include "acpi-sensors-interface.h"
#define ACPI_THERMAL_ZONE_BASE_DIR "/proc/acpi/thermal_zone"
#define ACPI_THERMAL_BASE_DIR "/proc/acpi/thermal"
/* for error handling */
#define ACPI_DEVICE_FILE_ERROR (acpi_sensors_interface_device_file_error_quark())
enum {
ACPI_DEVICE_FILE_OPEN_ERROR,
ACPI_DEVICE_FILE_READ_ERROR
};
static void acpi_sensors_interface_add_sensor(SensorsApplet *sensors_applet, const gchar *path) {
gchar *dirname;
gchar *id;
dirname = g_path_get_dirname(path);
id = g_path_get_basename(dirname);
g_free(dirname);
sensors_applet_add_sensor(sensors_applet,
path,
id,
_("CPU"),
ACPI,
TRUE,
TEMP_SENSOR,
CPU_ICON);
g_free(id);
}
/* recursive function to find sensors in a given path - once found
will call function to add sensor to the sensors_list */
static void acpi_sensors_interface_find_sensors(SensorsApplet *sensors_applet, const gchar *path) {
GDir *dir;
FILE *fp;
const gchar* new_file;
gchar *new_path, *filename;
if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
filename = g_path_get_basename(path);
if (g_strrstr(filename, "temperature") || g_strrstr(filename, "status")) {
/* also test can actually open file for
reading */
if ((fp = fopen(path, "r")) != NULL) {
fclose(fp);
acpi_sensors_interface_add_sensor(sensors_applet, path);
}
}
g_free(filename);
}
/* if is a directory (but not a symlinked dir as this
will lead us in circular loops) descend into it and look
for a sensor dir
*/
if (g_file_test(path, G_FILE_TEST_IS_DIR) && !g_file_test(path, G_FILE_TEST_IS_SYMLINK)) {
dir = g_dir_open(path, 0, NULL);
if (dir != NULL) {
while(new_file = g_dir_read_name(dir)) {
new_path = g_strdup_printf("%s/%s", path, new_file);
acpi_sensors_interface_find_sensors(sensors_applet, new_path);
g_free(new_path);
}
g_dir_close(dir);
}
}
}
/* to be called to setup for acpi sensors */
void acpi_sensors_interface_init(SensorsApplet *sensors_applet) {
sensors_applet_register_sensors_interface(sensors_applet,
ACPI,
acpi_sensors_interface_get_sensor_value);
/* call function to recursively look for sensors
starting at the defined base directory */
acpi_sensors_interface_find_sensors(sensors_applet, ACPI_THERMAL_ZONE_BASE_DIR);
acpi_sensors_interface_find_sensors(sensors_applet, ACPI_THERMAL_BASE_DIR);
}
/* for error handling */
static GQuark acpi_sensors_interface_device_file_error_quark(void) {
static GQuark quark = 0;
gchar *string;
if (quark == 0) {
string = g_strdup_printf("%s-device-file-error", sensor_interface[ACPI]);
quark = g_quark_from_string(string);
g_free(string);
}
return quark;
}
gdouble acpi_sensors_interface_get_sensor_value(const gchar *path,
const gchar *id,
SensorType type,
GError **error) {
/* to open and access the value of each sensor */
FILE *fp;
gfloat sensor_value =-1.0f;
gchar units[32];
if (NULL == (fp = fopen(path, "r"))) {
g_set_error(error, ACPI_DEVICE_FILE_ERROR, ACPI_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path);
return;
}
if (fscanf(fp, "temperature: %f %31s", &sensor_value, units) < 1) {
g_set_error(error, ACPI_DEVICE_FILE_ERROR, ACPI_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path);
fclose(fp);
return;
}
fclose(fp);
/* need to convert if units are deciKelvin */
if (g_ascii_strcasecmp(units, "dK") == 0) {
sensor_value = (sensor_value / 10.0) - 273.0;
}
return (gdouble)sensor_value;
}
syntax highlighted by Code2HTML, v. 0.9.1