/*
* 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 "pmu-sys-sensors-interface.h"
#include "sensors-applet.h"
#define PMU_SYS_BASE_DIR "/sys"
#define SENSOR1 "sensor1"
#define CPU "cpu"
#define SENSOR2 "sensor2"
#define GPU "gpu"
#define TEMPERATURE "_temperature"
#define FAN_SPEED "_fan_speed"
/* for error handling */
#define PMU_SYS_DEVICE_FILE_ERROR (pmu_sys_sensors_interface_device_file_error_quark())
enum {
PMU_SYS_DEVICE_FILE_OPEN_ERROR,
PMU_SYS_DEVICE_FILE_READ_ERROR
};
static void pmu_sys_sensors_interface_add_sensor(SensorsApplet *sensors_applet, const gchar *path) {
gchar *filename;
gchar *label = NULL;
gboolean enable;
SensorType sensor_type;
const gchar *icon_filename = NULL;
filename = g_path_get_basename(path);
if (g_ascii_strcasecmp(filename, SENSOR1 TEMPERATURE) == 0 || g_ascii_strcasecmp(filename, CPU TEMPERATURE) == 0) {
label = g_strdup(_("CPU"));
sensor_type = TEMP_SENSOR;
enable = TRUE;
icon_filename = CPU_ICON;
} else if (g_ascii_strcasecmp(filename, SENSOR2 TEMPERATURE) == 0 || g_ascii_strcasecmp(filename, GPU TEMPERATURE) == 0) {
label = g_strdup(_("GPU"));
sensor_type = TEMP_SENSOR;
enable = TRUE;
icon_filename = GPU_ICON;
} else if (g_ascii_strcasecmp(filename, SENSOR1 FAN_SPEED) == 0|| g_ascii_strcasecmp(filename, CPU FAN_SPEED) == 0) {
label = g_strdup(_("FAN"));
sensor_type = FAN_SENSOR;
enable = TRUE;
icon_filename = FAN_ICON;
} else {
/* disable all other sensors */
enable = FALSE;
}
/* only add these 3 sensors */
if (enable) {
sensors_applet_add_sensor(sensors_applet,
path,
filename,
label,
PMU_SYS,
enable,
sensor_type,
icon_filename);
}
g_free(filename);
if (label != NULL) {
g_free(label);
}
}
/* recursive function to find sensors in a given path - once found
will call function to add sensor to the sensors_list */
static void pmu_sys_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, SENSOR1 TEMPERATURE) == filename ||
g_strrstr(filename, SENSOR2 TEMPERATURE) == filename ||
g_strrstr(filename, SENSOR1 FAN_SPEED) == filename ||
g_strrstr(filename, CPU TEMPERATURE) == filename ||
g_strrstr(filename, GPU TEMPERATURE) == filename ||
g_strrstr(filename, CPU FAN_SPEED) == filename) {
/* also test can actually open file for
reading */
if ((fp = fopen(path, "r")) != NULL) {
fclose(fp);
pmu_sys_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);
pmu_sys_sensors_interface_find_sensors(sensors_applet, new_path);
g_free(new_path);
}
g_dir_close(dir);
}
}
}
/* to be called to setup for sys sensors */
void pmu_sys_sensors_interface_init(SensorsApplet *sensors_applet) {
sensors_applet_register_sensors_interface(sensors_applet,
PMU_SYS,
pmu_sys_sensors_interface_get_sensor_value);
/* call function to recursively look for sensors
starting at the defined base directory */
pmu_sys_sensors_interface_find_sensors(sensors_applet, PMU_SYS_BASE_DIR);
}
/* for error handling */
static GQuark pmu_sys_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[PMU_SYS]);
quark = g_quark_from_string(string);
g_free(string);
}
return quark;
}
/* returns the value of the sensor_list at the given iter, or if an
error occurs, instatiates error with an error message */
gdouble pmu_sys_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, dummy;
if (NULL == (fp = fopen(path, "r"))) {
g_set_error(error, PMU_SYS_DEVICE_FILE_ERROR, PMU_SYS_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path);
return;
}
switch(type) {
case FAN_SENSOR:
if (fscanf(fp, "%f (%f rpm)", &dummy, &sensor_value) != 2) {
g_set_error(error, PMU_SYS_DEVICE_FILE_ERROR, PMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path);
fclose(fp);
return;
}
break;
case TEMP_SENSOR:
if (fscanf(fp, "%f", &sensor_value) != 1) {
g_set_error(error, PMU_SYS_DEVICE_FILE_ERROR, PMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path);
fclose(fp);
return;
}
break;
default:
/* should only have added temp or fan sensors */
g_assert_not_reached();
}
fclose(fp);
return (gdouble)sensor_value;
}
syntax highlighted by Code2HTML, v. 0.9.1