⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensors.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that 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.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "gkrellm.h"#include "gkrellm-private.h"#include "gkrellm-sysdeps.h"/* Useful info:|  http://mbm.livewiredev.com/|		Look up boards here for sensor chip and temperature sensor type|		so sensor[1,2,3] can be set correctly in sensors.conf.*/  /* On Linux, the sensor id_name includes the parent chip directory, so  |  "lm78/temp" will be a id_name, and not just "temp".  This is to  |  allow unique identification in case of multiple "temp" files.  |  ie, more than 1 chip directory, each with a "temp" file.  */typedef struct _sensor	{	gchar		*name;			/* cpuX, mb, Vx name mapped to this sensor */	gchar		*name_locale;	/* gdk_draw compat */	gchar		*default_label;	/* Only voltages have default labels */	gchar		*path;			/* Pathname to sensor data or device file */	gchar		*id_name;		/* Unique sensor identifier for config */	gint		type;	gint		id;	gint		iodev;	gint		inter;	gint		enabled;	gint		group;	gint		location;		/* default, Proc panel, or cpu panel */	gfloat		factor,			/* Scale sensor reading		*/				offset;			/* Add to sensor reading	*/	gfloat		default_factor,				default_offset;	gchar		*vref_name;	struct _sensor				*vref;			/* A neg volt may be function of a ref volt */	gboolean	has_config;	gfloat		value,				raw_value;	gboolean	value_valid;	GkrellmAlert *alert;	void		(*cb_alert)();	gpointer	cb_alert_data;	gpointer	smon;	}	Sensor;static GList	*sensor_list	= NULL;static GList	*temp_order_list,	/* For ordering from the config. */				*fan_order_list,				*volt_order_list;static gboolean	using_new_config,				need_disk_temperature_update;static gboolean	(*get_temperature)(gchar *name, gint id,			gint iodev, gint inter, gfloat *t);static gboolean	(*get_fan)(gchar *name, gint id,			gint iodev, gint inter, gfloat *f);static gboolean	(*get_voltage)(gchar *name, gint id,			gint iodev, gint inter, gfloat *v);static void read_sensors_config(void);voidgkrellm_sensors_client_divert(gboolean (*get_temp_func)(),			gboolean (*get_fan_func)(), gboolean (*get_volt_func)())	{	get_temperature = get_temp_func;	get_fan = get_fan_func;	get_voltage = get_volt_func;	}static gbooleansetup_sensor_interface(void)	{	if (!get_temperature && !_GK.client_mode && gkrellm_sys_sensors_init())		{		get_temperature = gkrellm_sys_sensors_get_temperature;		get_fan = gkrellm_sys_sensors_get_fan;		get_voltage = gkrellm_sys_sensors_get_voltage;		}	return get_temperature ? TRUE : FALSE;	}voidgkrellm_sensors_set_group(gpointer sr, gint group)	{	Sensor	*sensor = (Sensor *) sr;	if (sensor)		sensor->group = group;	}gpointergkrellm_sensors_add_sensor(gint type, gchar *sensor_path, gchar *id_name,		gint id, gint iodev, gint inter,		gfloat factor, gfloat offset, gchar *vref, gchar *default_label)	{	Sensor	*sensor;	gchar	*r;	if (!id_name || !*id_name || type < 0 || type > 2)		return NULL;	sensor = g_new0(Sensor, 1);	sensor->id_name = g_strdup(id_name);	if (sensor_path)		sensor->path = g_strdup(sensor_path);	else		sensor->path = g_strdup(id_name);	if (!default_label)		{		r = strrchr(id_name, '/');		default_label = r ? r+1 : id_name;		}	gkrellm_locale_dup_string(&sensor->name, default_label,				&sensor->name_locale);	sensor->default_label = g_strdup(default_label);	sensor->default_factor = sensor->factor = factor;	sensor->default_offset = sensor->offset = offset;	sensor->type = type;	sensor->id = id;	sensor->iodev = iodev;	sensor->inter = inter;	if (type == SENSOR_VOLTAGE && vref)		sensor->vref_name = g_strdup(vref);	sensor_list = g_list_append(sensor_list, sensor);	return (gpointer) sensor;	}/* ======================================================================== */static gboolean	use_threads,				thread_data_valid,				units_fahrenheit;static gboolean thread_busy;static gpointerread_sensors_thread(void *data)	{	GList	*list;	Sensor	*sensor;	for (list = sensor_list; list; list = list->next)		{		sensor = (Sensor *) list->data;		if (!sensor->enabled)			continue;		if (sensor->type == SENSOR_TEMPERATURE && get_temperature)			(*get_temperature)(sensor->path, sensor->id,				sensor->iodev, sensor->inter, &sensor->raw_value);		if (sensor->type == SENSOR_FAN && get_fan)			(*get_fan)(sensor->path, sensor->id,				sensor->iodev, sensor->inter, &sensor->raw_value);		if (sensor->type == SENSOR_VOLTAGE && get_voltage)			(*get_voltage)(sensor->path, sensor->id,				sensor->iodev, sensor->inter, &sensor->raw_value);		}	thread_busy = FALSE;	return NULL;	}static voidrun_sensors_thread(void)	{	if (thread_busy)		return;	thread_busy = TRUE;	g_thread_create(read_sensors_thread, NULL, FALSE, NULL);	}  /* Sort so that sensors are ordered: temp, fan, voltage.  */static gintstrcmp_sensor_path(Sensor *s1, Sensor *s2)	{	if (s1->type == SENSOR_TEMPERATURE && s2->type != SENSOR_TEMPERATURE)		return -1;	if (s1->type != SENSOR_TEMPERATURE && s2->type == SENSOR_TEMPERATURE)		return 1;	if (s1->type == SENSOR_FAN && s2->type != SENSOR_FAN)		return -1;	if (s1->type != SENSOR_FAN && s2->type == SENSOR_FAN)		return 1;	return strcmp(s1->id_name, s2->id_name);	}static voidappend_sensor_to_order_list(Sensor *sr)	{	if (sr->type == SENSOR_TEMPERATURE)		temp_order_list = g_list_append(temp_order_list, sr);	else if (sr->type == SENSOR_FAN)		fan_order_list = g_list_append(fan_order_list, sr);	else if (sr->type == SENSOR_VOLTAGE)		volt_order_list = g_list_append(volt_order_list, sr);	}  /* Remove embedded "-i2c-" or "-isa-" from lm_sensors chip names so  |  there can be a chance for config name sysfs compatibility.  This function  |  here in sensors.c is a kludge.  Give user configs a chance to get  |  converted and then move this function to sysdeps/linux.c where it  |  belongs.  |  Munge names like w83627hf-isa-0290 to w83627hf-0-0290  |                or w83627hf-i2c-0-0290 to w83627hf-0-0290  |  lm_sensor i2c bus address may not be 4 digits, eg: w83782d-i2c-0-2d  |  and for that we want: w83782d-0-002d  */voidgkrellm_sensors_linux_name_fix(gchar *id_name)	{#if defined(__linux__)	gchar	*s;	gint	len, bus = 0;	guint	addr = 0;	len = strlen(id_name) + 1;	if ((s = strstr(id_name, "-i2c-")) != NULL)		{		sscanf(s + 5, "%d-%x", &bus, &addr);		snprintf(s, len - (s - id_name), "-%d-%04x", bus, addr);		}	else if ((s = strstr(id_name, "-isa-")) != NULL)		{		*(s + 1) = '0';		memmove(s + 2, s + 4, strlen(s + 4) + 1);		}#endif	}  /* This is called as sensors are read from the config and I will want to  |  re-order the sensors_list to reflect the config order. Re-ordering is  |  done by appending found sensors to type specific lists and later the  |  sensors_list will be rebuilt from the ordered type lists.  If the  |  id_name is found in the sensor_list, assign the label to it.  */static Sensor *map_sensor_label(gchar *label, gchar *name)	{	GList		*list;	Sensor		*sr;	gkrellm_sensors_linux_name_fix(name);		/* XXX temporary, remove me */	for (list = sensor_list; list; list = list->next)		{		sr = (Sensor *) list->data;		if (!sr->has_config && !strcmp(sr->id_name, name))			{			gkrellm_locale_dup_string(&sr->name, label, &sr->name_locale);			append_sensor_to_order_list(sr);			sr->has_config = TRUE;			return sr;			}		}	return NULL;	}gbooleangkrellm_sensors_available(void)	{	return (sensor_list || _GK.demo) ? TRUE : FALSE;	}  /* The cpu and proc monitors both need a couple of sensor decals  |  created on their panels.  The left one will only display fan speeds  |  while the right one will display both fan and temps depending on modes.  */voidgkrellm_sensors_create_decals(GkrellmPanel *p, gint style_id,			GkrellmDecal **dsensor, GkrellmDecal **dfan)	{	GkrellmStyle		*style;	GkrellmMargin		*m;	GkrellmTextstyle	*ts;	GkrellmDecal		*ds	= NULL,						*df	= NULL;	gint				w, w_avail;	if (sensor_list || _GK.demo)		{		style = gkrellm_panel_style(style_id);		m = gkrellm_get_style_margins(style);		ts = gkrellm_panel_alt_textstyle(style_id);		w_avail = gkrellm_chart_width() - m->left - m->right;		df = gkrellm_create_decal_text(p, "8888", ts, style, -1, -1, 0);		/* Sensor decal (fan and/or temp) carves out space remaining to right.		|  Try to get enough for .1 deg resolution, otherwise what is left.		*/		w = gkrellm_gdk_string_width(ts->font, "188.8F") + ts->effect;		if (w > w_avail - df->w - 3)			w = gkrellm_gdk_string_width(ts->font, "88.8C") + ts->effect;		ds = gkrellm_create_decal_text(p, "8.C", ts, style, -1, -1, w);		ds->x = w_avail + m->left - w;		df->x = m->left;		}	*dsensor = ds;	*dfan = df;	}voidgkrellm_sensor_draw_fan_decal(GkrellmPanel *p, GkrellmDecal *d, gfloat f)	{	gchar	buf[8];	gint	w;	if (!p || !d)		return;	snprintf(buf, sizeof(buf), "%.0f", f);	w = gkrellm_gdk_string_width(d->text_style.font, buf)				+ d->text_style.effect;	d->x_off = d->w - w;	if (d->x_off < 0)		d->x_off = 0;	gkrellm_draw_decal_text(p, d, buf, 0);	}voidgkrellm_sensor_draw_temperature_decal(GkrellmPanel *p, GkrellmDecal *d,				gfloat t, gchar units)	{	gchar	*s, buf[8];	gint	w;	if (!p || !d)		return;	snprintf(buf, sizeof(buf), "%.1f%c", t, units);	if ((s = strchr(buf, '.')) == NULL)		s = strchr(buf, ',');			/* Locale may use commas */	w = gkrellm_gdk_string_width(d->text_style.font, buf)				+ d->text_style.effect;	if (w > d->w + 1)		{		snprintf(buf, sizeof(buf), "%.0f%c", t, units);		w = gkrellm_gdk_string_width(d->text_style.font, buf)				+ d->text_style.effect;		}		d->x_off = d->w - w;	if (d->x_off < 0)		d->x_off = 0;	gkrellm_draw_decal_text(p, d, buf, 0 /* no longer used */);	}static Sensor *lookup_sensor_from_id_name(gchar *name)	{	GList	*list;	Sensor	*s;	if (!name)		return NULL;	gkrellm_sensors_linux_name_fix(name);		/* XXX temporary, remove me */	for (list = sensor_list; list; list = list->next)		{		s = (Sensor *) list->data;		if (!strcmp(s->id_name, name))			return s;		}	return NULL;	}  /* Given a in0, in1, ... name as a reference to use for a sensor,  |  find the sensor with that name for the same chip as sr.  */static Sensor *lookup_vref(Sensor *sr, gchar *name)	{	GList	*list;	Sensor	*sv;	gchar	*s, buf[128];	snprintf(buf, 96, "%s", sr->id_name);	s = strrchr(buf, '/');	if (s)		++s;	else		s = buf;	snprintf(s, 31, "%s", name);	for (list = sensor_list; list; list = list->next)		{		sv = (Sensor *) list->data;		if (   sv->type == SENSOR_VOLTAGE			&& !strcmp(sv->id_name, buf)		   )			return sv;		}	return NULL;	}static voidcb_command_process(GkrellmAlert *alert, gchar *src, gchar *buf, gint size,			Sensor *sensor)	{	gchar		c, *s, *fmt;	gint		len;	if (!buf || size < 1)		return;	--size;	*buf = '\0';	if (!src)		return;	for (s = src; *s != '\0' && size > 0; ++s)		{		len = 1;		if (*s == '$' && *(s + 1) != '\0')			{			if ((c = *(s + 1)) == 'H')				len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name());			else if (c == 's')				{				if (sensor->type == SENSOR_FAN)					fmt = "%.0f";				else if (sensor->type == SENSOR_TEMPERATURE)					fmt = "%.1f";				else					fmt = "%.2f";				len = snprintf(buf, size, fmt, sensor->value);				}			else if (c == 'l')				len = snprintf(buf, size, "%s", sensor->name_locale);			++s;			}		else			*buf = *s;		size -= len;		buf += len;		}	*buf = '\0';	}GkrellmAlert *gkrellm_sensor_alert(gpointer sr)	{	if (!sr)		return NULL;	return ((Sensor *) sr)->alert;	}voidgkrellm_sensor_alert_connect(gpointer sr, void (*cb_func)(), gpointer data)	{	Sensor	*sensor = (Sensor *) sr;	if (!sensor)		return;	sensor->cb_alert = cb_func;	sensor->cb_alert_data = data;	gkrellm_alert_trigger_connect(sensor->alert, cb_func, data);	gkrellm_alert_command_process_connect(sensor->alert,				cb_command_process, sensor);	gkrellm_reset_alert_soft(sensor->alert);	}static gbooleansensor_read_temperature(Sensor *sensor, gfloat *temp, gchar *units)	{	gfloat	t = 0;	gint	found_temp = FALSE;	if (sensor && get_temperature)		{		found_temp = thread_data_valid ? TRUE			: (*get_temperature)(sensor->path, sensor->id,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -