diff options
Diffstat (limited to 'sensors-applet/plugins')
49 files changed, 4325 insertions, 0 deletions
diff --git a/sensors-applet/plugins/Makefile.am b/sensors-applet/plugins/Makefile.am new file mode 100644 index 00000000..74dc7574 --- /dev/null +++ b/sensors-applet/plugins/Makefile.am @@ -0,0 +1,55 @@ +NULL= + +DIST_SUBDIRS = \ + acpi \ + dummy \ + udisks2 \ + hddtemp \ + i2c-proc \ + i2c-sys \ + i8k \ + ibm-acpi \ + libsensors \ + mbmon \ + netbsd \ + nvidia \ + omnibook \ + pmu-sys \ + smu-sys \ + sonypi \ + $(NULL) + +SUBDIRS = \ + acpi \ + hddtemp \ + i8k \ + ibm-acpi \ + mbmon \ + omnibook \ + pmu-sys \ + smu-sys \ + sonypi + +if DUMMYPLUGIN +SUBDIRS += dummy +endif + +if UDISKS2 +SUBDIRS += udisks2 +endif + +if LIBSENSORS +SUBDIRS += libsensors +else +SUBDIRS += i2c-proc i2c-sys +endif + +if NETBSD +SUBDIRS += netbsd +endif + +if NVIDIA +SUBDIRS += nvidia +endif + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/acpi/Makefile.am b/sensors-applet/plugins/acpi/Makefile.am new file mode 100644 index 00000000..dfa9f5bc --- /dev/null +++ b/sensors-applet/plugins/acpi/Makefile.am @@ -0,0 +1,24 @@ +# ACPI plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libacpi.la + +libacpi_la_SOURCES = \ + acpi-plugin.h \ + acpi-plugin.c + +libacpi_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libacpi_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/acpi/acpi-plugin.c b/sensors-applet/plugins/acpi/acpi-plugin.c new file mode 100644 index 00000000..fc361139 --- /dev/null +++ b/sensors-applet/plugins/acpi/acpi-plugin.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "acpi-plugin.h" + +const gchar *plugin_name = "acpi"; + +#define ACPI_THERMAL_ZONE_BASE_DIR "/proc/acpi/thermal_zone" +#define ACPI_THERMAL_BASE_DIR "/proc/acpi/thermal" + +enum { + ACPI_DEVICE_FILE_OPEN_ERROR, + ACPI_DEVICE_FILE_READ_ERROR +}; + +static void acpi_plugin_add_sensor(GList **sensors, const gchar *path) { + gchar *dirname; + gchar *id; + + dirname = g_path_get_dirname(path); + id = g_path_get_basename(dirname); + g_free(dirname); + + sensors_applet_plugin_add_sensor(sensors, + path, + id, + _("CPU"), + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + g_free(id); +} + +static void acpi_plugin_test_sensor(GList **sensors, const gchar *path) { + gchar *filename; + filename = g_path_get_basename(path); + + if (g_ascii_strcasecmp(filename, "temperature") == 0 || + g_ascii_strcasecmp(filename, "status") == 0) { + acpi_plugin_add_sensor(sensors, path); + } + g_free(filename); +} + +/* to be called to setup for acpi sensors and returns the list of found sensors */ +static GList *acpi_plugin_init(void) { + GList *sensors = NULL; + + /* call function to recursively look for sensors + starting at the defined base directory */ + sensors_applet_plugin_find_sensors(&sensors, ACPI_THERMAL_ZONE_BASE_DIR, acpi_plugin_test_sensor); + sensors_applet_plugin_find_sensors(&sensors, ACPI_THERMAL_BASE_DIR, acpi_plugin_test_sensor); + return sensors; +} + +static gdouble acpi_plugin_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, SENSORS_APPLET_PLUGIN_ERROR, ACPI_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return sensor_value; + } + + if (fscanf(fp, "temperature: %f %31s", &sensor_value, units) < 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, ACPI_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return sensor_value; + } + 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; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return acpi_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return acpi_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/acpi/acpi-plugin.h b/sensors-applet/plugins/acpi/acpi-plugin.h new file mode 100644 index 00000000..122d82c7 --- /dev/null +++ b/sensors-applet/plugins/acpi/acpi-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ACPI_PLUGIN_H +#define ACPI_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* ACPI_PLUGIN_H*/ diff --git a/sensors-applet/plugins/dummy/Makefile.am b/sensors-applet/plugins/dummy/Makefile.am new file mode 100644 index 00000000..7c350479 --- /dev/null +++ b/sensors-applet/plugins/dummy/Makefile.am @@ -0,0 +1,26 @@ +# Dummy plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + + +plugin_LTLIBRARIES = libdummy.la + +libdummy_la_SOURCES = \ + dummy-plugin.h \ + dummy-plugin.c + +libdummy_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) + +libdummy_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/dummy/dummy-plugin.c b/sensors-applet/plugins/dummy/dummy-plugin.c new file mode 100644 index 00000000..9dfd0142 --- /dev/null +++ b/sensors-applet/plugins/dummy/dummy-plugin.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2018 info-cppsp <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Dummy plugin to be able to test msa in a VM */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <time.h> +#include <stdlib.h> +#include "dummy-plugin.h" + +// remove // from next line for syslog debug +//#define DPDBG 1 + +#ifdef DPDBG +#include <syslog.h> +#endif + +const gchar *plugin_name = "dummy"; + +static void dummy_plugin_get_sensors(GList **sensors) { + + /* dummy HDD temp sensor */ + sensors_applet_plugin_add_sensor(sensors, + "/sys/devices/platform/it87.656/hwmon/hwmon1/temp2_input", + "temp2", + "CPU", + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + + /* dummy HDD temp sensor */ + sensors_applet_plugin_add_sensor(sensors, + "/sys/devices/platform/it87.656/hwmon/hwmon1/fan1_input", + "fan1", + "fan1", + FAN_SENSOR, + TRUE, + FAN_ICON, + DEFAULT_GRAPH_COLOR); + + /* dummy HDD temp sensor */ + sensors_applet_plugin_add_sensor(sensors, + "HDD 2154884654-5648HG-546821", + "Disk Temperature", + "HDD 2154884654", + TEMP_SENSOR, + TRUE, + HDD_ICON, + DEFAULT_GRAPH_COLOR); + +} + +/* this is the function called every refresh cycle */ +static gdouble dummy_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + switch (type) { + case TEMP_SENSOR: + return (gdouble) (rand() % 40 + 20); + break; + + case FAN_SENSOR: + return (gdouble) (rand() % 3000); + break; + + default: + g_assert_not_reached(); + } + +} + +/* API functions */ +const gchar *sensors_applet_plugin_name(void) { + return plugin_name; +} + +static GList *dummy_plugin_init(void) { + GList *sensors = NULL; + + /* init random number generation */ + srand(time(NULL)); + + dummy_plugin_get_sensors(&sensors); + + return sensors; +} + +GList *sensors_applet_plugin_init(void) { + return dummy_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return dummy_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/dummy/dummy-plugin.h b/sensors-applet/plugins/dummy/dummy-plugin.h new file mode 100644 index 00000000..e5c4b853 --- /dev/null +++ b/sensors-applet/plugins/dummy/dummy-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 info-cppsp <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DUMMY_PLUGIN_H +#define DUMMY_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* DUMMY_PLUGIN_H */ diff --git a/sensors-applet/plugins/hddtemp/Makefile.am b/sensors-applet/plugins/hddtemp/Makefile.am new file mode 100644 index 00000000..a1bff03e --- /dev/null +++ b/sensors-applet/plugins/hddtemp/Makefile.am @@ -0,0 +1,24 @@ +# HDDTEMP plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libhddtemp.la + +libhddtemp_la_SOURCES = \ + hddtemp-plugin.h \ + hddtemp-plugin.c + +libhddtemp_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libhddtemp_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/hddtemp/hddtemp-plugin.c b/sensors-applet/plugins/hddtemp/hddtemp-plugin.c new file mode 100644 index 00000000..c540172e --- /dev/null +++ b/sensors-applet/plugins/hddtemp/hddtemp-plugin.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include <unistd.h> +#include <glib.h> +#include "hddtemp-plugin.h" + +const gchar *plugin_name = "hddtemp"; + +#define HDDTEMP_SERVER_IP_ADDRESS "127.0.0.1" +#define HDDTEMP_PORT_NUMBER 7634 +#define HDDTEMP_OUTPUT_BUFFER_LENGTH 1024 + +enum { + HDDTEMP_SOCKET_OPEN_ERROR, + HDDTEMP_SOCKET_CONNECT_ERROR, + HDDTEMP_GIOCHANNEL_ERROR, + HDDTEMP_GIOCHANNEL_READ_ERROR +}; + +static gchar buffer[HDDTEMP_OUTPUT_BUFFER_LENGTH]; + +static const gchar *hddtemp_plugin_query_hddtemp_daemon(GError **error) { + guint output_length = 0; + static gboolean first_run = TRUE; + + struct sockaddr_in address; + static gint64 previous_query_time; + gint64 current_query_time; + + if (first_run) { + // initialise previous time + previous_query_time = g_get_monotonic_time (); + } + current_query_time = g_get_monotonic_time (); + + /* only actually query if more than 60 seconds has elapsed as + hddtemp daemon will only actually send a new value if is > 60 + seconds */ + if (first_run || current_query_time - previous_query_time > G_TIME_SPAN_MINUTE) { + int sockfd; + ssize_t n; + gchar *pc; + + previous_query_time = current_query_time; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + // couldn't open socket + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, HDDTEMP_SOCKET_OPEN_ERROR, "Error opening socket for hddtemp"); + return NULL; + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr(HDDTEMP_SERVER_IP_ADDRESS); + address.sin_port = htons(HDDTEMP_PORT_NUMBER); + + if (connect(sockfd, (struct sockaddr *)&address, (socklen_t)sizeof(address)) == -1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, HDDTEMP_SOCKET_CONNECT_ERROR, "Error connecting to hddtemp daemon on port %i on %s", htons(HDDTEMP_PORT_NUMBER), HDDTEMP_SERVER_IP_ADDRESS); + close(sockfd); + return NULL; + } + memset(buffer, 0, sizeof(buffer)); + pc = buffer; + while ((n = read(sockfd, pc, sizeof(buffer) - output_length)) > 0) { + output_length += n; + pc += n; + } + /* always null terminate the end of the buffer */ + buffer[MIN(output_length, sizeof(buffer) - 1)] = '\0'; + close(sockfd); + first_run = FALSE; + } + + return buffer; +} + +static void hddtemp_plugin_get_sensors(GList **sensors) { + GError *error = NULL; + const gchar *hddtemp_output; + gchar **output_vector = NULL, **pv; + + hddtemp_output = hddtemp_plugin_query_hddtemp_daemon(&error); + + if (error) { + g_error_free(error); + return; + } + + if (hddtemp_output[0] != '|') { + g_debug("Error in format of string returned from hddtemp daemon: char at [0] should be \"|\", instead whole output is: \"%s\"", hddtemp_output); + return; + } + + /* for each sensor the output will contain four strings ie + |/dev/hda|WDC WD800JB-00ETA0|32|C||/dev/hdb|???|ERR|*| + note the repetition -----^ */ + + /* + pv[0 + 5*n] empty + pv[1 + 5*n] device name + pv[2 + 5*n] disk label + pv[3 + 5*n] temperature + pv[4 + 5*n] unit + pv[5 + 5*n] empty + */ + + pv = output_vector = g_strsplit(hddtemp_output, "|", -1); + + while(pv[1] != NULL) { + if (g_strcmp0(pv[2], "") != 0 && + g_strcmp0(pv[3], "") != 0 && + g_strcmp0(pv[4], "") != 0 && + (!(g_ascii_strcasecmp(pv[2], "???") == 0 || + g_ascii_strcasecmp(pv[3], "ERR") == 0 || + g_ascii_strcasecmp(pv[4], "*") == 0))) { + + sensors_applet_plugin_add_sensor(sensors, + pv[1], // must be dynamically allocated + pv[1], // must be dynamically allocated + pv[2], // must be dynamically allocated + TEMP_SENSOR, + FALSE, + HDD_ICON, + DEFAULT_GRAPH_COLOR); + } + pv += 5; + } + g_strfreev(output_vector); +} + +/* to be called to setup for hddtemp sensors */ +static GList *hddtemp_plugin_init(void) { + GList *sensors = NULL; + hddtemp_plugin_get_sensors(&sensors); + return sensors; +} + +/* returns the value of the sensor_list at the given iter, or if an + error occurs, instatiates error with an error message */ +static gdouble hddtemp_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + const gchar *hddtemp_output; + gchar **output_vector = NULL, **pv; + + gfloat sensor_value = -1.0f; + + hddtemp_output = hddtemp_plugin_query_hddtemp_daemon(error); + + if (*error) { + return sensor_value; + } + + if (hddtemp_output[0] != '|') { + g_debug("Error in format of string returned from hddtemp daemon: char at [0] should be \"|\", instead whole output is: \"%s\"", hddtemp_output); + return sensor_value; + } + + /* for each sensor the output will contain four strings ie + |/dev/hda|WDC WD800JB-00ETA0|32|C||/dev/hdb|???|ERR|*| + note the repetition -----^ + + pv[0 + 5*n] empty + pv[1 + 5*n] device name + pv[2 + 5*n] disk label + pv[3 + 5*n] temperature + pv[4 + 5*n] unit + pv[5 + 5*n] empty + */ + + pv = output_vector = g_strsplit(hddtemp_output, "|", -1); + + while(pv[1] != NULL) { + if (g_ascii_strcasecmp(pv[1], path) == 0) { + sensor_value = (gfloat)(g_ascii_strtod(pv[3], NULL)); + + /* always return sensor values in celsius */ + if (pv[4][0] == 'F') { + sensor_value = (sensor_value - 32.0) * 5.0 / 9.0; + } + break; + } + pv += 5; + } + g_strfreev(output_vector); + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return hddtemp_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + return hddtemp_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/hddtemp/hddtemp-plugin.h b/sensors-applet/plugins/hddtemp/hddtemp-plugin.h new file mode 100644 index 00000000..697d9d2c --- /dev/null +++ b/sensors-applet/plugins/hddtemp/hddtemp-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef HDDTEMP_PLUGIN_H +#define HDDTEMP_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* HDDTEMP_PLUGIN_H */ diff --git a/sensors-applet/plugins/i2c-proc/Makefile.am b/sensors-applet/plugins/i2c-proc/Makefile.am new file mode 100644 index 00000000..0e165dcf --- /dev/null +++ b/sensors-applet/plugins/i2c-proc/Makefile.am @@ -0,0 +1,24 @@ +# I2C-PROC plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libi2c-proc.la + +libi2c_proc_la_SOURCES = \ + i2c-proc-plugin.h \ + i2c-proc-plugin.c + +libi2c_proc_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libi2c_proc_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.c b/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.c new file mode 100644 index 00000000..4a63a8ac --- /dev/null +++ b/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <locale.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "i2c-proc-plugin.h" + +const gchar *plugin_name = "i2c-proc"; + +#define I2C_PROC_BASE_DIR "/proc/sys/dev/sensors" + +enum { + I2C_PROC_DEVICE_FILE_OPEN_ERROR, + I2C_PROC_DEVICE_FILE_READ_ERROR +}; + +static void i2c_proc_plugin_add_sensor(GList **sensors, const gchar *path) { + gchar *filename; + gchar *label; + gboolean enable; + SensorType sensor_type; + IconType icon_type = GENERIC_ICON; + + filename = g_path_get_basename(path); + + /* setup temp2 as CPU sensor and enable it */ + if (g_ascii_strcasecmp(filename, "temp2") == 0) { + sensor_type = TEMP_SENSOR; + label = g_strdup(_("CPU")); + enable = TRUE; + icon_type = CPU_ICON; + } else { + label = g_strdup(filename); + + switch(filename[0]) { + case 'c': /* currents are "curr?" */ + sensor_type = CURRENT_SENSOR; + break; + case 'f': /* fans are "fan?" */ + sensor_type = FAN_SENSOR; + icon_type = FAN_ICON; + break; + case 'i': /* voltages are "in?" */ + sensor_type = VOLTAGE_SENSOR; + break; + case 't': /* temps are "temp?" */ + sensor_type = TEMP_SENSOR; + break; + case 'v': /* vids are just vid */ + sensor_type = VOLTAGE_SENSOR; + break; + default: + /* SHOULDN'T BE ABLE TO GET HERE!! */ + g_debug("error in i2c-proc sensor detection code - unhandled sensor filename %s", filename); + g_free(filename); + g_free(label); + return; + } + /* disable all other sensors */ + enable = FALSE; + } + + sensors_applet_plugin_add_sensor(sensors, + path, + filename, + label, + sensor_type, + enable, + icon_type, + DEFAULT_GRAPH_COLOR); + + g_free(filename); + g_free(label); +} + +static void i2c_proc_plugin_test_sensor(GList **sensors, const gchar *path) { + gchar *filename; + + filename = g_path_get_basename(path); + /* see if filename starts with any of the sensor prefixes */ + if (g_str_has_prefix(filename, "curr") || + (g_str_has_prefix(filename, "fan") && + !g_str_has_prefix(filename, "fan_div")) || + g_str_has_prefix(filename, "in") || + g_str_has_prefix(filename, "temp") || + g_str_has_prefix(filename, "vid")) { + + i2c_proc_plugin_add_sensor(sensors, path); + } + g_free(filename); + +} + +/* to be called to setup for proc sensors */ +static GList *i2c_proc_plugin_init(void) { + GList *sensors = NULL; + + /* call function to recursively look for sensors + starting at the defined base directory */ + sensors_applet_plugin_find_sensors(&sensors, I2C_PROC_BASE_DIR, i2c_proc_plugin_test_sensor); + return sensors; +} + +static gdouble i2c_proc_plugin_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 float1, float2, float3; + gint int1, int2; + + gfloat sensor_value = -1.0; + + gchar *old_locale = NULL; + + /* always use C locale */ + if (NULL == (old_locale = setlocale(LC_NUMERIC, "C"))) { + g_warning("Could not change locale to C locale for reading i2c-proc device files.. will try regardless"); + } + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + } else { + switch (type) { + case CURRENT_SENSOR: + if (fscanf(fp, "%f %f %f", &float1, &float2, &float3) != 3) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } else { + sensor_value = float3; + } + break; + + case FAN_SENSOR: + if (fscanf(fp, "%d %d", &int1, &int2) != 2) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } else { + sensor_value = (gfloat)int2; + } + break; + + case VOLTAGE_SENSOR: + /* is it CPU_VID or IN */ + switch(id[0]) { + case 'i': + if (fscanf(fp, "%f %f %f", &float1, &float2, &float3) != 3) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } else { + sensor_value = float3; + } + break; + + case 'v': + /* want first value in file as float */ + if (fscanf(fp, "%f", &float1) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } else { + sensor_value = float1; + } + break; + default: + g_debug("error in i2c-proc sensor read value function code - unhandled sensor id %s", id); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } + break; + + case TEMP_SENSOR: + if (fscanf(fp, "%f %f %f", &float1, &float2, &float3) != 3) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_PROC_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } else { + sensor_value = float3; + } + break; + } /* end switch */ + fclose(fp); + } + + if (NULL != old_locale) { + setlocale(LC_NUMERIC, old_locale); + } + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return i2c_proc_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return i2c_proc_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.h b/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.h new file mode 100644 index 00000000..17655225 --- /dev/null +++ b/sensors-applet/plugins/i2c-proc/i2c-proc-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SENSORS_LIST_I2C_PROC_H +#define SENSORS_LIST_I2C_PROC_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* SENSORS_LIST_I2C_PROC_H */ diff --git a/sensors-applet/plugins/i2c-sys/Makefile.am b/sensors-applet/plugins/i2c-sys/Makefile.am new file mode 100644 index 00000000..a0be6129 --- /dev/null +++ b/sensors-applet/plugins/i2c-sys/Makefile.am @@ -0,0 +1,24 @@ +# I2C-SYS plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libi2c-sys.la + +libi2c_sys_la_SOURCES = \ + i2c-sys-plugin.h \ + i2c-sys-plugin.c + +libi2c_sys_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libi2c_sys_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.c b/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.c new file mode 100644 index 00000000..411f98de --- /dev/null +++ b/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "i2c-sys-plugin.h" + +const gchar *plugin_name = "i2c-sys"; + +#define I2C_SYS_BASE_DIR "/sys" + +enum { + I2C_SYS_DEVICE_FILE_OPEN_ERROR, + I2C_SYS_DEVICE_FILE_READ_ERROR +}; + +static void i2c_sys_plugin_add_sensor(GList **sensors, const gchar *path) { + gchar *filename; + gchar *id; + gchar *label; + gboolean enable; + guint sensor_type; + IconType icon_type = GENERIC_ICON; + + filename = g_path_get_basename(path); + + /* setup temp2 as CPU sensor and enable it */ + if (g_ascii_strcasecmp(filename, "temp2_input") == 0) { + id = g_strndup(filename, 5); + label = g_strdup(_("CPU")); + sensor_type = TEMP_SENSOR; + enable = TRUE; + icon_type = CPU_ICON; + } else { + switch(filename[0]) { + case 'c': /* either current or cpu?_vid sensor */ + if (filename[1] == 'u') { /* currents are curr?_input */ + id = g_strndup(filename, 5); + label = g_strndup(filename, 5); + sensor_type = CURRENT_SENSOR; + } else { /* cpu_vid is cpu?_vid */ + id = g_strdup(filename); + label = g_strdup(filename); + sensor_type = VOLTAGE_SENSOR; + } + break; + + case 'f': /* fans are "fan?_input" */ + id = g_strndup(filename, 4); + label = g_strndup(filename, 4); + sensor_type = FAN_SENSOR; + icon_type = FAN_ICON; + break; + + case 't': /* temps are "temp?_input" */ + id = g_strndup(filename, 5); + label = g_strndup(filename, 5); + sensor_type = TEMP_SENSOR; + break; + + case 'i': /* voltages are "in?_input" */ + id = g_strndup(filename, 3); + label = g_strndup(filename, 3); + sensor_type = VOLTAGE_SENSOR; + break; + + default: + /* SHOULDN'T BE ABLE * TO GET HERE!! */ + g_warning("filename:\"%s\" begins with a charater that is not covered by this switch statement... not adding sensor", filename); + g_free(filename); + + return; + } + + /* disable all other sensors */ + enable = FALSE; + } + + sensors_applet_plugin_add_sensor(sensors, + path, + id, + label, + sensor_type, + enable, + icon_type, + DEFAULT_GRAPH_COLOR); + + g_free(filename); + g_free(id); + g_free(label); +} + +static void i2c_sys_plugin_test_sensor(GList **sensors, const gchar *path) { +gchar *filename; + +filename = g_path_get_basename(path); + +if ((g_str_has_suffix(filename, "_input") && + (g_str_has_prefix(filename, "temp") || + g_str_has_prefix(filename, "fan") || + g_str_has_prefix(filename, "curr") || + g_str_has_prefix(filename, "in"))) || + (g_str_has_prefix(filename, "cpu") && + (g_str_has_suffix(filename, "_vid")))) { + + i2c_sys_plugin_add_sensor(sensors, path); +} + + g_free(filename); +} + +/* to be called to setup for sys sensors */ +static GList *i2c_sys_plugin_init(void) { + GList *sensors = NULL; + + /* call function to recursively look for sensors + starting at the defined base directory */ + sensors_applet_plugin_find_sensors(&sensors, + I2C_SYS_BASE_DIR, + i2c_sys_plugin_test_sensor); + return sensors; +} + +static gdouble i2c_sys_plugin_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; + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_SYS_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + + if (fscanf(fp, "%f", &sensor_value) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + fclose(fp); + + if (type != FAN_SENSOR) { + sensor_value /= 1000.0; + } + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return i2c_sys_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return i2c_sys_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.h b/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.h new file mode 100644 index 00000000..d1e5ece7 --- /dev/null +++ b/sensors-applet/plugins/i2c-sys/i2c-sys-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef I2C_SYS_PLUGIN_H +#define I2C_SYS_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* I2C_SYS_PLUGIN_H*/ diff --git a/sensors-applet/plugins/i8k/Makefile.am b/sensors-applet/plugins/i8k/Makefile.am new file mode 100644 index 00000000..20739603 --- /dev/null +++ b/sensors-applet/plugins/i8k/Makefile.am @@ -0,0 +1,24 @@ +# I8K plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libi8k.la + +libi8k_la_SOURCES = \ + i8k-plugin.h \ + i8k-plugin.c + +libi8k_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libi8k_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/i8k/i8k-plugin.c b/sensors-applet/plugins/i8k/i8k-plugin.c new file mode 100644 index 00000000..e213d045 --- /dev/null +++ b/sensors-applet/plugins/i8k/i8k-plugin.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "i8k-plugin.h" + +const gchar *plugin_name = "i8k"; + +#define I8K_DEVICE_PATH "/proc/i8k" +#define I8K_DEVICE_FILE "i8k" + +enum { + I8K_DEVICE_FILE_OPEN_ERROR, + I8K_DEVICE_FILE_READ_ERROR +}; + +static void i8k_plugin_setup_manually(GList **sensors) { + if (g_file_test(I8K_DEVICE_PATH, G_FILE_TEST_EXISTS)) { + /* with i8k have only 3 fixed sensors, all accessed + from the I8K_DEVICE_PATH */ + sensors_applet_plugin_add_sensor(sensors, + I8K_DEVICE_PATH, + "temp1", + _("CPU"), + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + + sensors_applet_plugin_add_sensor(sensors, + I8K_DEVICE_PATH, + "fan1", + _("FAN1"), + FAN_SENSOR, + FALSE, + FAN_ICON, + DEFAULT_GRAPH_COLOR); + + sensors_applet_plugin_add_sensor(sensors, + I8K_DEVICE_PATH, + "fan2", + _("FAN2"), + FAN_SENSOR, + FALSE, + FAN_ICON, + DEFAULT_GRAPH_COLOR); + } +} + +/* to be called externally to setup for i8k sensors */ +static GList *i8k_plugin_init(void) { + GList *sensors = NULL; + + i8k_plugin_setup_manually(&sensors); + + return sensors; +} + +static +gdouble i8k_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + /* to open and access the value of each sensor */ + FILE *fp; + gint cpu_temp, fan1_status, fan2_status, fan1_rpm, fan2_rpm; + gint sensor_value; + gint space_count, file_length; + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I8K_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + + space_count = 0; + file_length = 0; + + /* count spaces but stop if have counted 100 characters and + still not found a space (to avoid infinite loop if file + format error) */ + while (file_length < 100 && space_count < 3) { + if (fgetc(fp) == ' ') { + space_count++; + } + file_length++; + } + + if (fscanf(fp, "%d %d %d %d %d", &cpu_temp, &fan1_status, &fan2_status, &fan1_rpm, &fan2_rpm) != 5) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I8K_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + fclose(fp); + + switch (type) { + case TEMP_SENSOR: + sensor_value = cpu_temp; + break; + + case FAN_SENSOR: + switch (id[3]) { + case '1': + sensor_value = fan1_rpm; + break; + + case '2': + sensor_value = fan2_rpm; + break; + + default: + g_error("Error in i8k sensor get value function code for id %s", id); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I8K_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + return -1.0; + } + break; + + default: + g_error("Unknown sensor type passed as parameter to i8k sensor interface, cannot get value for this sensor"); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I8K_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + return -1.0; + } // end switch (sensor_type) + + return (gdouble)sensor_value; + +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return i8k_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return i8k_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/i8k/i8k-plugin.h b/sensors-applet/plugins/i8k/i8k-plugin.h new file mode 100644 index 00000000..9d1ab31e --- /dev/null +++ b/sensors-applet/plugins/i8k/i8k-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef I8K_PLUGIN_H +#define I8K_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* I8K_PLUGIN_H */ diff --git a/sensors-applet/plugins/ibm-acpi/Makefile.am b/sensors-applet/plugins/ibm-acpi/Makefile.am new file mode 100644 index 00000000..9656387b --- /dev/null +++ b/sensors-applet/plugins/ibm-acpi/Makefile.am @@ -0,0 +1,24 @@ +# IBM-ACPI plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libibm-acpi.la + +libibm_acpi_la_SOURCES = \ + ibm-acpi-plugin.h \ + ibm-acpi-plugin.c + +libibm_acpi_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libibm_acpi_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.c b/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.c new file mode 100644 index 00000000..ae8f8ab9 --- /dev/null +++ b/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "ibm-acpi-plugin.h" + +const gchar *plugin_name = "ibm-acpi"; + +#define IBM_ACPI_TEMPERATURE_FILE "/proc/acpi/ibm/thermal" +#define IBM_ACPI_FAN_FILE "/proc/acpi/ibm/fan" + +/* sensor id's */ +#define CPU "CPU" +#define MPCI "mPCI" +#define HDD "HDD" +#define GPU "GPU" +#define BAT0 "BAT0" +#define BAT1 "BAT1" +#define FAN "FAN" + +enum { + IBM_ACPI_FILE_OPEN_ERROR, + IBM_ACPI_FILE_READ_ERROR +}; + +static void ibm_acpi_plugin_setup_manually(GList **sensors) { + if (g_file_test(IBM_ACPI_TEMPERATURE_FILE, G_FILE_TEST_EXISTS)) { + gchar *label; + + /* with Ibm_Acpi have 8 fixed sensors, all accessed + from the IBM_ACPI_TEMPERATURE_FILE */ + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + CPU, + _(CPU), + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + MPCI, + _("MiniPCI"), + TEMP_SENSOR, + FALSE, + GENERIC_ICON, + DEFAULT_GRAPH_COLOR); + + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + HDD, + _(HDD), + TEMP_SENSOR, + FALSE, + HDD_ICON, + DEFAULT_GRAPH_COLOR); + + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + GPU, + _(GPU), + TEMP_SENSOR, + FALSE, + GPU_ICON, + DEFAULT_GRAPH_COLOR); + + label = g_strdup_printf("%s %d", _("Battery"), 0); + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + BAT0, + label, + TEMP_SENSOR, + FALSE, + BATTERY_ICON, + DEFAULT_GRAPH_COLOR); + + g_free(label); + + label = g_strdup_printf("%s %d", _("Battery"), 0); + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_TEMPERATURE_FILE, + BAT1, + label, + TEMP_SENSOR, + FALSE, + BATTERY_ICON, + DEFAULT_GRAPH_COLOR); + + g_free(label); + } + + if (g_file_test(IBM_ACPI_FAN_FILE, G_FILE_TEST_EXISTS)) { + sensors_applet_plugin_add_sensor(sensors, + IBM_ACPI_FAN_FILE, + FAN, + _("Fan"), + FAN_SENSOR, + FALSE, + FAN_ICON, + DEFAULT_GRAPH_COLOR); + + } +} + +/* to be called externally to setup for ibm_acpi sensors */ +static +GList *ibm_acpi_plugin_init(void) { + GList *sensors = NULL; + + ibm_acpi_plugin_setup_manually(&sensors); + + return sensors; +} + +static +gdouble ibm_acpi_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + /* to open and access the value of each sensor */ + FILE *fp; + gint sensor_value = 0; + gint cpu_temp, minipci_temp, hdd_temp, gpu_temp, bat0_temp, bat1_temp, unknown0, unknown1; + gint fan_speed; + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, IBM_ACPI_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + + switch (type) { + case TEMP_SENSOR: + if (fscanf(fp, "temperatures: %d %d %d %d %d %d %d %d", &cpu_temp, &minipci_temp, &hdd_temp, &gpu_temp, &bat0_temp, &unknown0, &bat1_temp, &unknown1) != 8) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, IBM_ACPI_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + + if (g_ascii_strcasecmp(id, CPU) == 0) { + sensor_value = cpu_temp; + } else if (g_ascii_strcasecmp(id, MPCI) == 0) { + sensor_value = minipci_temp; + } else if (g_ascii_strcasecmp(id, HDD) == 0) { + sensor_value = hdd_temp; + } else if (g_ascii_strcasecmp(id, GPU) == 0) { + sensor_value = gpu_temp; + } else if (g_ascii_strcasecmp(id, BAT0) == 0) { + sensor_value = bat0_temp; + } else if (g_ascii_strcasecmp(id, BAT1) == 0) { + sensor_value = bat1_temp; + } + break; + + case FAN_SENSOR: + /*fscanf(fp, "%*[^\n]");*/ /* Skip to the End of the Line */ + /*fscanf(fp, "%*1[\n]");*/ /* Skip One Newline */ + if (fscanf(fp, "%*[^\n]%*1[\n]speed: %d", &fan_speed) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, IBM_ACPI_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + + if (g_ascii_strcasecmp(id, "FAN") == 0) { + sensor_value = fan_speed; + } + break; + + default: + g_error("Unknown sensor type passed as parameter to ibm-acpi sensor interface, cannot get value for this sensor"); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, IBM_ACPI_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + + fclose(fp); + + return (gdouble)sensor_value; + +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return ibm_acpi_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return ibm_acpi_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.h b/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.h new file mode 100644 index 00000000..cfc9f30e --- /dev/null +++ b/sensors-applet/plugins/ibm-acpi/ibm-acpi-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IBM_ACPI_PLUGIN_H +#define IBM_ACPI_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* IBM_ACPI_PLUGIN_H */ + diff --git a/sensors-applet/plugins/libsensors/Makefile.am b/sensors-applet/plugins/libsensors/Makefile.am new file mode 100644 index 00000000..99dc1472 --- /dev/null +++ b/sensors-applet/plugins/libsensors/Makefile.am @@ -0,0 +1,25 @@ +plugindir = $(libdir)/mate-sensors-applet/plugins + +# libsensors plugin +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(LIBSENSORS_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = liblibsensors.la + +liblibsensors_la_SOURCES = \ + libsensors-plugin.h \ + libsensors-plugin.c + +liblibsensors_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) $(LIBSENSORS_LIBS) +liblibsensors_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/libsensors/libsensors-plugin.c b/sensors-applet/plugins/libsensors/libsensors-plugin.c new file mode 100644 index 00000000..ebe8b025 --- /dev/null +++ b/sensors-applet/plugins/libsensors/libsensors-plugin.c @@ -0,0 +1,471 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SENSORS_SENSORS_H +#include <sensors/sensors.h> +#endif + +#include "libsensors-plugin.h" + +const gchar *plugin_name = "libsensors"; + +GHashTable *hash_table = NULL; + +enum { + LIBSENSORS_CHIP_PARSE_ERROR, + LIBSENSORS_MISSING_FEATURE_ERROR, + LIBSENSORS_REGEX_URL_COMPILE_ERROR, + LIBSENSORS_CHIP_NOT_FOUND_ERROR +}; + +#if SENSORS_API_VERSION < 0x400 +#define LIBSENSORS_CONFIG_FILE "/etc/sensors.conf" +#define LIBSENSORS_ALTERNATIVE_CONFIG_FILE "/usr/local/etc/sensors.conf" +#endif + +GRegex *uri_re; + +static char *get_chip_name_string(const sensors_chip_name *chip) { + char *name; + +#if SENSORS_API_VERSION < 0x400 + /* taken from lm-sensors:prog/sensors/main.c:sprintf_chip_name */ + switch (chip->bus) { + case SENSORS_CHIP_NAME_BUS_ISA: + name = g_strdup_printf ("%s-isa-%04x", chip->prefix, chip->addr); + break; + case SENSORS_CHIP_NAME_BUS_DUMMY: + name = g_strdup_printf ("%s-%s-%04x", chip->prefix, chip->busname, chip->addr); + break; + case SENSORS_CHIP_NAME_BUS_PCI: + name = g_strdup_printf ("%s-pci-%04x", chip->prefix, chip->addr); + break; + default: + name = g_strdup_printf ("%s-i2c-%d-%02x", chip->prefix, chip->bus, chip->addr); + break; + } + +#else +/* adapted from lm-sensors:prog/sensors/main.c:sprintf_chip_name in lm-sensors-3.0 */ +#define BUF_SIZE 200 + static char buf[BUF_SIZE]; + if (sensors_snprintf_chip_name(buf, BUF_SIZE, chip) < 0) { + name = NULL; + } else { + name = g_strdup (buf); + } +#endif + + return name; +} + +#if SENSORS_API_VERSION < 0x400 +static SensorType get_sensor_type (const char *name) { + SensorType type = CURRENT_SENSOR; + + if (g_strrstr(name, "in")) { + type = VOLTAGE_SENSOR; + } + else if (g_strrstr(name, "fan")) { + type = FAN_SENSOR; + } + else if (g_strrstr(name, "temp")) { + type = TEMP_SENSOR; + } else { + g_debug("sensor %s not recognised as either voltage, fan or temp sensor - assuming is a current sensor", name); + type = CURRENT_SENSOR; + } + return type; +} + +/* If a sensor is 'interesting' to us then return its label, otherwise NULL. */ +static char *get_sensor_interesting_label (sensors_chip_name chip, int feature) { + char *label; + + if (sensors_get_ignored(chip, feature) && (sensors_get_label(chip, feature, &label) == 0)) { + if (! (strcmp ("alarms", label) == 0 || strncmp ("sensor", label, 6) == 0)) { + return label; + } else { + free (label); + } + } + + return NULL; +} + +static const sensors_feature_data * get_sensor_min_max(const sensors_chip_name *chip, + int *n1, int *n2, + int number, + gdouble *low_value, + gdouble *high_value) { + + const sensors_feature_data *data; + double value; + + /* The sub features are returned directly after the main feature by + sensors_get_all_features(), so no need to iterate over all features */ + while ((data = sensors_get_all_features (*chip, n1, n2)) != NULL && data->mapping == number) { + if ((data->mode & SENSORS_MODE_R) && (sensors_get_feature(*chip, data->number, &value) == 0) && data->name != NULL) { + + if (g_str_has_suffix(data->name, "_min")) { + *low_value = value; + g_debug("overriding low value of sensor %s with value %f", data->name, value); + } else if (g_str_has_suffix(data->name, "_max")) { + *high_value = value; + g_debug("overriding high value of sensor %s with value %f", data->name, value); + } + } + } + return data; +} + +#endif + +static IconType get_sensor_icon (SensorType type) { + switch (type) { + case TEMP_SENSOR: + return CPU_ICON; + case FAN_SENSOR: + return FAN_ICON; + default: + return GENERIC_ICON; + } +} + +#if SENSORS_API_VERSION < 0x400 +static void check_sensor_with_data(GList **sensors, + const char * const chip_name, + const sensors_chip_name *chip, + int *n1, int *n2, + const sensors_feature_data *data) { + + char *label; + double value; + SensorsAppletSensorInfo *sensor_info = NULL; + + /* ... some of which are boring ... */ + if ((label = get_sensor_interesting_label (*chip, data->number))) { + /* ... and some of which are actually sensors */ + if ((data->mode & SENSORS_MODE_R) && + (data->mapping == SENSORS_NO_MAPPING) && + (sensors_get_feature(*chip, data->number, &value) == 0)) { /* make sure we can actually get a value for it */ + + SensorType type; + gboolean visible; + IconType icon; + gdouble low_value, high_value; + + gchar *url; + + type = get_sensor_type (data->name); + visible = (type == TEMP_SENSOR ? TRUE : FALSE); + icon = get_sensor_icon(type); + + /* the 'path' contains all the information we need to identify this sensor later */ + url = g_strdup_printf ("sensor://%s/%d", chip_name, data->number); + + /* get low and high values */ + sensors_applet_plugin_default_sensor_limits(type, &low_value, &high_value); + + data = get_sensor_min_max(chip, n1, n2, data->number, &low_value, &high_value); + if (data != NULL) { + /* try adding this one */ + /* at this point we have called sensors_get_all_features() and stopped when we have a potential new sensor, so make sure we try this as well - do a recursive call */ + check_sensor_with_data(sensors, chip_name, chip, n1, n2, data); + } + + g_hash_table_insert(hash_table, g_strdup(url), (void *)chip); + /* the id identifies a particular sensor for the user; */ + /* we default to the label returned by libsensors */ + sensors_applet_plugin_add_sensor_with_limits(sensors, + url, + label, + label, + type, + visible, + low_value, + high_value, + icon, + DEFAULT_GRAPH_COLOR); + g_free(url); + } + free (label); + } + +} + +#endif + +static GList *libsensors_plugin_get_sensors(void) { + const sensors_chip_name *chip_name; + GList *sensors = NULL; + +#if SENSORS_API_VERSION < 0x400 + FILE *file; + int i; + g_debug("%s: using libsensors version < 4", __FUNCTION__); + + /* try to open config file, otherwise try alternate config + * file - if neither succeed, exit */ + if ((file = fopen (LIBSENSORS_CONFIG_FILE, "r")) == NULL) { + if ((file = fopen (LIBSENSORS_ALTERNATIVE_CONFIG_FILE, "r")) == NULL) { + g_debug("%s: error opening libsensors config file... ", __FUNCTION__); + return sensors; + } + } + + /* at this point should have an open config file, if is not + * valid, close file and return */ + if (sensors_init(file) != 0) { + fclose(file); + g_debug("%s: error initing libsensors from config file...", __FUNCTION__); + return sensors; + } + fclose(file); + + /* libsensors exposes a number of chips - ... */ + i = 0; + while ((chip_name = sensors_get_detected_chips (&i)) != NULL) { + char *chip_name_string; + const sensors_feature_data *data; + int n1 = 0, n2 = 0; + + chip_name_string = get_chip_name_string(chip_name); + + /* ... each of which has one or more 'features' ... */ + while ((data = sensors_get_all_features (*chip_name, &n1, &n2)) != NULL) { /* error */ + /* fill in list for us */ + check_sensor_with_data(&sensors, chip_name_string, chip_name, &n1, &n2, data); + } + g_free (chip_name_string); + } + +#else + g_debug("%s: using libsensors version >= 4", __FUNCTION__); + + int nr = 0; + if (sensors_init(NULL) != 0) { + g_debug("%s: error initing libsensors", __FUNCTION__); + return sensors; + } + + while ((chip_name = sensors_get_detected_chips(NULL, &nr))) { + + char *chip_name_string, *label; + const sensors_subfeature *input_feature; + const sensors_subfeature *low_feature; + const sensors_subfeature *high_feature; + const sensors_feature *main_feature; + SensorType type; + gint nr1 = 0; + gdouble value, low, high; + gchar *path; + gboolean visible; + IconType icon; + + chip_name_string = get_chip_name_string(chip_name); + if (chip_name_string == NULL) { + g_debug("%s: %d: error getting name string for sensor: %s\n", __FILE__, __LINE__, chip_name->path); + continue; + } + + while ((main_feature = sensors_get_features(chip_name, &nr1))) { + switch (main_feature->type) { + case SENSORS_FEATURE_IN: + type = VOLTAGE_SENSOR; + input_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_IN_INPUT); + low_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_IN_MIN); + high_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_IN_MAX); + break; + + case SENSORS_FEATURE_FAN: + type = FAN_SENSOR; + input_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_FAN_INPUT); + low_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_FAN_MIN); + /* no fan max feature */ + high_feature = NULL; + break; + + case SENSORS_FEATURE_TEMP: + type = TEMP_SENSOR; + input_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_TEMP_INPUT); + low_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_TEMP_MIN); + high_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_TEMP_MAX); + if (!high_feature) + high_feature = sensors_get_subfeature(chip_name, main_feature, SENSORS_SUBFEATURE_TEMP_CRIT); + break; + + default: + g_debug("%s: %d: error determining type for: %s\n", __FILE__, __LINE__, chip_name_string); + continue; + } + + if (!input_feature) { + g_debug("%s: %d: could not get input subfeature for: %s\n", __FILE__, __LINE__, chip_name_string); + continue; + } + + /* if still here we got input feature so get label */ + label = sensors_get_label(chip_name, main_feature); + if (!label) { + g_debug("%s: %d: error: could not get label for: %s\n", __FILE__, __LINE__, chip_name_string); + continue; + } + + g_assert(chip_name_string && label); + + icon = get_sensor_icon(type); + visible = (type == TEMP_SENSOR ? TRUE : FALSE); + sensors_applet_plugin_default_sensor_limits(type, &low, &high); + if (low_feature) { + sensors_get_value(chip_name, low_feature->number, &low); + } + + if (high_feature) { + sensors_get_value(chip_name, high_feature->number, &high); + } + + if (sensors_get_value(chip_name, input_feature->number, &value) < 0) { + g_debug("%s: %d: error: could not get value for input feature of sensor: %s\n", __FILE__, __LINE__, chip_name_string); + free(label); + continue; + } + + g_debug("for chip %s (type %s) got label %s and value %f", chip_name_string, + (type == TEMP_SENSOR ? "temp" : (type == FAN_SENSOR ? "fan" : (type == VOLTAGE_SENSOR ? "voltage" : "error"))), label, value); + + path = g_strdup_printf ("sensor://%s/%d", chip_name_string, input_feature->number); + g_hash_table_insert(hash_table, g_strdup(path), (void *)chip_name); + + sensors_applet_plugin_add_sensor_with_limits(&sensors, + path, + label, + label, + type, + visible, + low, + high, + icon, + DEFAULT_GRAPH_COLOR); + } + g_free(chip_name_string); + + } +#endif + + return sensors; +} + +static gdouble libsensors_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + gdouble result = 0; + GMatchInfo *m; + + /* parse the uri into a (chip, feature) tuplet */ + g_regex_match (uri_re, path, 0, &m); + if (g_match_info_matches (m)) { + const sensors_chip_name *found_chip; + int feature; + + if ((found_chip = g_hash_table_lookup(hash_table, path)) != NULL) { + gdouble value; + gchar *feature_str; + + feature_str = g_match_info_fetch (m, 1); + feature = atoi(feature_str); + g_free (feature_str); + +#if SENSORS_API_VERSION < 0x400 + /* retrieve the value of the feature */ + if (sensors_get_feature (*found_chip, feature, &value) == 0) { + result = value; + } else { + g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR, LIBSENSORS_MISSING_FEATURE_ERROR, "Error retrieving sensor value"); + } +#else + if (sensors_get_value(found_chip, feature, &value) >= 0) { + result = value; + } else { + g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR, LIBSENSORS_MISSING_FEATURE_ERROR, "Error retrieving sensor value"); + } +#endif + + } else { + g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR, LIBSENSORS_CHIP_NOT_FOUND_ERROR, "Chip not found"); + } + } else { + g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR, LIBSENSORS_REGEX_URL_COMPILE_ERROR, "Error compiling URL regex: Not match"); + } + g_match_info_free (m); + return result; +} + +static GList *libsensors_plugin_init(void) { + GError *err = NULL; + + /* compile the regular expressions */ + uri_re = g_regex_new ("^sensor://[a-z0-9_-]+/([0-9]+)$", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_ANCHORED, &err); + if (err) { + g_debug("Error compiling regexp: %s\nnot initing libsensors sensors interface", err->message); + g_error_free (err); + return NULL; + } + + /* create hash table to associate path strings with sensors_chip_name + * pointers - make sure it free's the keys strings on destroy */ + hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + return libsensors_plugin_get_sensors(); +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return libsensors_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return libsensors_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/libsensors/libsensors-plugin.h b/sensors-applet/plugins/libsensors/libsensors-plugin.h new file mode 100644 index 00000000..2c4f1ddc --- /dev/null +++ b/sensors-applet/plugins/libsensors/libsensors-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBSENSORS_SENSORS_INTERFACE_H +#define LIBSENSORS_SENSORS_INTERFACE_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* LIBSENSORS_SENSORS_INTERFACE_H*/ diff --git a/sensors-applet/plugins/mbmon/Makefile.am b/sensors-applet/plugins/mbmon/Makefile.am new file mode 100644 index 00000000..f1e1b56e --- /dev/null +++ b/sensors-applet/plugins/mbmon/Makefile.am @@ -0,0 +1,24 @@ +# MBMON plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libmbmon.la + +libmbmon_la_SOURCES = \ + mbmon-plugin.h \ + mbmon-plugin.c + +libmbmon_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libmbmon_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/mbmon/mbmon-plugin.c b/sensors-applet/plugins/mbmon/mbmon-plugin.c new file mode 100644 index 00000000..e5f7c20f --- /dev/null +++ b/sensors-applet/plugins/mbmon/mbmon-plugin.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2010 Daniele Napolitano <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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 */ + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif + +#include <unistd.h> +#include "mbmon-plugin.h" + +const gchar *plugin_name = "mbmon"; + +#define MBMON_SERVER_IP_ADDRESS "127.0.0.1" +#define MBMON_PORT_NUMBER 411 +#define MBMON_OUTPUT_BUFFER_LENGTH 1024 + +enum { + MBMON_SOCKET_OPEN_ERROR, + MBMON_SOCKET_CONNECT_ERROR, + MBMON_GIOCHANNEL_ERROR, + MBMON_GIOCHANNEL_READ_ERROR +}; + +static const gchar *mbmon_plugin_query_mbmon_daemon(GError **error) { + static gboolean first_run = FALSE; + gint output_length = 0; + gchar *pc; + + struct sockaddr_in address; + static char* buffer = NULL; + static gint64 previous_query_time; + gint64 current_query_time; + + if (NULL == buffer) { + /* initialise buffer and current time */ + buffer = g_new0(char, MBMON_OUTPUT_BUFFER_LENGTH); + previous_query_time = g_get_monotonic_time (); + first_run = TRUE; + } + current_query_time = g_get_monotonic_time (); + + /* only query if more than 2 seconds has elapsed, + mbmon daemon will send a new value every 2 seconds */ + if (first_run || current_query_time - previous_query_time > 2 * G_TIME_SPAN_SECOND) { + int sockfd; + ssize_t n; + + previous_query_time = current_query_time; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + /* couldn't open socket */ + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, MBMON_SOCKET_OPEN_ERROR, "Error opening socket for mbmon"); + return NULL; + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr(MBMON_SERVER_IP_ADDRESS); + address.sin_port = htons(MBMON_PORT_NUMBER); + + if (connect(sockfd, (struct sockaddr *)&address, (socklen_t)sizeof(address)) == -1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, MBMON_SOCKET_CONNECT_ERROR, "Error connecting to mbmon daemon on port %i on %s", htons(MBMON_PORT_NUMBER), MBMON_SERVER_IP_ADDRESS); + return NULL; + } + + pc = buffer; + while ((n = read(sockfd, pc, MBMON_OUTPUT_BUFFER_LENGTH - output_length)) > 0) { + output_length += n; + pc = &pc[n]; + } + /* always null terminate the end of the buffer + * regardless of how much stuff is in it already */ + buffer[output_length] = '\0'; + close(sockfd); + } + + return buffer; +} + +static SensorType get_sensor_type (const char *name) { + SensorType type = CURRENT_SENSOR; + + if (g_strrstr(name, "FAN")) { + type = FAN_SENSOR; + } else if (g_strrstr(name, "TEMP")) { + type = TEMP_SENSOR; + } else { + type = VOLTAGE_SENSOR; + } + return type; +} + +static IconType get_sensor_icon (SensorType type) { + switch (type) { + case TEMP_SENSOR: + return CPU_ICON; + case FAN_SENSOR: + return FAN_ICON; + default: + return GENERIC_ICON; + } +} + +static void mbmon_plugin_get_sensors(GList **sensors) { + + GError *error = NULL; + const gchar *mbmon_output; + gchar **output_vector = NULL, **pv; + + mbmon_output = mbmon_plugin_query_mbmon_daemon(&error); + + if (error) { + g_error_free(error); + return; + } + + pv = output_vector = g_strsplit(mbmon_output, "\n", -1); + + while(pv[0] != NULL) { + gchar **pv2; + + pv2 = g_strsplit(pv[0], ":", -1); + gchar *name, *label; + SensorType type; + gboolean visible; + IconType icon; + gdouble low_value, high_value; + + type = get_sensor_type(pv2[0]); + icon = get_sensor_icon(type); + name = g_strstrip(pv2[0]); + label = NULL; + visible = (type == TEMP_SENSOR ? TRUE : FALSE); + + if(type == VOLTAGE_SENSOR) { + if(g_strrstr(name, "VC0")) { + label = g_strdup("Core Voltage 1"); + } else if(g_strrstr(name, "VC1")) { + label = g_strdup("Core Voltage 2"); + } else if(g_strrstr(name, "V33")) { + label = g_strdup("+3.3v Voltage"); + } else if(g_strrstr(name, "V50P")) { + label = g_strdup("+5v Voltage"); + } else if(g_strrstr(name, "V12P")) { + label = g_strdup("+12v Voltage"); + } else if(g_strrstr(name, "V12N")) { + label = g_strdup("-12v Voltage"); + } else if(g_strrstr(name, "V50N")) { + label = g_strdup("-5v Voltage"); + } + } + + label = (label == NULL ? name : label); + + sensors_applet_plugin_default_sensor_limits(type, &low_value, &high_value); + + sensors_applet_plugin_add_sensor_with_limits(sensors, + name, + name, + label, + type, + visible, + low_value, + high_value, + icon, + DEFAULT_GRAPH_COLOR); + + g_strfreev(pv2); + pv++; + } + g_strfreev(output_vector); + +} + +/* to be called to setup for mbmon sensors */ +static GList *mbmon_plugin_init(void) { + GList *sensors = NULL; + mbmon_plugin_get_sensors(&sensors); + return sensors; +} + +/* returns the value of the sensor_list at the given iter, or if an + error occurs, instatiates error with an error message */ +static gdouble mbmon_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + const gchar *mbmon_output; + gchar **output_vector = NULL, **pv, **pv2; + + gfloat sensor_value = -1.0f; + + mbmon_output = mbmon_plugin_query_mbmon_daemon(error); + + if (*error) { + return sensor_value; + } + + pv = output_vector = g_strsplit(mbmon_output, "\n", -1); + + while(pv[0] != NULL) { + if (g_strrstr(pv[0], path) != NULL) { + + pv2 = g_strsplit(pv[0], ":", -1); + sensor_value = (gfloat)(g_ascii_strtod(pv2[1], NULL)); + g_strfreev(pv2); + break; + } + pv++; + } + g_strfreev(output_vector); + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return mbmon_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return mbmon_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/mbmon/mbmon-plugin.h b/sensors-applet/plugins/mbmon/mbmon-plugin.h new file mode 100644 index 00000000..74333fda --- /dev/null +++ b/sensors-applet/plugins/mbmon/mbmon-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Daniele Napolitano <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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 + */ + +#ifndef MBMON_PLUGIN_H +#define MBMON_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* MBMON_PLUGIN_H */ diff --git a/sensors-applet/plugins/netbsd/Makefile.am b/sensors-applet/plugins/netbsd/Makefile.am new file mode 100644 index 00000000..d06f7bd7 --- /dev/null +++ b/sensors-applet/plugins/netbsd/Makefile.am @@ -0,0 +1,26 @@ +# NetBSD plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + + +plugin_LTLIBRARIES = libnetbsd.la + +libnetbsd_la_SOURCES = \ + netbsd-plugin.h \ + netbsd-plugin.c + +libnetbsd_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) -lprop + +libnetbsd_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/netbsd/netbsd-plugin.c b/sensors-applet/plugins/netbsd/netbsd-plugin.c new file mode 100644 index 00000000..ae413a9b --- /dev/null +++ b/sensors-applet/plugins/netbsd/netbsd-plugin.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2018 Jared McNeill <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <fcntl.h> +#include <unistd.h> +#include <prop/proplib.h> +#include <sys/envsys.h> + +#include "netbsd-plugin.h" + +static int sysmon_fd = -1; + +static gdouble netbsd_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + prop_dictionary_t dict; + prop_array_t array; + prop_object_iterator_t iter, siter; + prop_object_t obj, sobj; + const gchar *desc = NULL, *state = NULL; + gdouble sensor_val = -1.0f; + int64_t val; + + if (prop_dictionary_recv_ioctl(sysmon_fd, ENVSYS_GETDICTIONARY, &dict) == -1) + return sensor_val; + + iter = prop_dictionary_iterator(dict); + while ((obj = prop_object_iterator_next(iter)) != NULL) { + if (strcmp(path, prop_dictionary_keysym_cstring_nocopy(obj)) != 0) + continue; + + array = prop_dictionary_get_keysym(dict, obj); + siter = prop_array_iterator(array); + while ((sobj = prop_object_iterator_next(siter)) != NULL) { + if (prop_dictionary_get_cstring_nocopy(sobj, "description", &desc) == false) + continue; + if (strcmp(id, desc) != 0) + continue; + + prop_dictionary_get_cstring_nocopy(sobj, "state", &state); + prop_dictionary_get_int64(sobj, "cur-value", &val); + + if (strcmp(state, "valid") == 0) { + switch (type) { + case TEMP_SENSOR: + /* K to C */ + sensor_val = ((val - 273150000) / 1000000.0); + break; + case FAN_SENSOR: + /* RPM */ + sensor_val = (gdouble)val; + break; + case VOLTAGE_SENSOR: + /* uV to V */ + sensor_val = val / 1000000.0; + break; + default: + break; + } + } + break; + } + prop_object_iterator_release(siter); + break; + } + prop_object_iterator_release(iter); + + prop_object_release(dict); + + return sensor_val; +} + +static IconType netbsd_plugin_get_sensor_icon(const gchar *desc) { + IconType icontype = GENERIC_ICON; + + if (strcasestr(desc, "cpu") != NULL) + icontype = CPU_ICON; + else if (strcasestr(desc, "gpu") != NULL) + icontype = GPU_ICON; + else if (strcasestr(desc, "batt") != NULL) + icontype = BATTERY_ICON; + else if (strcasestr(desc, "mem") != NULL) + icontype = MEMORY_ICON; + else if (strcasestr(desc, "disk") != NULL || strcasestr(desc, "hdd") != NULL) + icontype = HDD_ICON; + + return icontype; +} + +static void netbsd_plugin_get_sensors(GList **sensors) { + prop_dictionary_t dict; + prop_array_t array; + prop_object_iterator_t iter, siter; + prop_object_t obj, sobj; + + sysmon_fd = open("/dev/sysmon", O_RDONLY); + if (sysmon_fd == -1) + return; + + if (prop_dictionary_recv_ioctl(sysmon_fd, ENVSYS_GETDICTIONARY, &dict) == -1) { + close(sysmon_fd); + return; + } + + iter = prop_dictionary_iterator(dict); + while ((obj = prop_object_iterator_next(iter)) != NULL) { + const gchar *path = prop_dictionary_keysym_cstring_nocopy(obj); + array = prop_dictionary_get_keysym(dict, obj); + siter = prop_array_iterator(array); + while ((sobj = prop_object_iterator_next(siter)) != NULL) { + const gchar *type = NULL, *desc = NULL; + if (prop_dictionary_get_cstring_nocopy(sobj, "type", &type) == false) + continue; + if (prop_dictionary_get_cstring_nocopy(sobj, "description", &desc) == false) + continue; + + SensorType sensortype; + if (strcmp(type, "Fan") == 0) + sensortype = FAN_SENSOR; + else if (strcmp(type, "Temperature") == 0) + sensortype = TEMP_SENSOR; + else if (strcmp(type, "Voltage AC") == 0 || strcmp(type, "Voltage DC") == 0) + sensortype = VOLTAGE_SENSOR; + else + continue; + + IconType icontype = netbsd_plugin_get_sensor_icon(desc); + + sensors_applet_plugin_add_sensor(sensors, + g_strdup(path), + g_strdup(desc), + g_strdup(desc), + sensortype, + TRUE, + icontype, + DEFAULT_GRAPH_COLOR); + } + prop_object_iterator_release(siter); + } + prop_object_iterator_release(iter); + + prop_object_release(dict); +} + +static GList *netbsd_plugin_init(void) { + GList *sensors = NULL; + + netbsd_plugin_get_sensors(&sensors); + + return sensors; +} + +/* API functions */ +const gchar *sensors_applet_plugin_name(void) { + return "netbsd"; +} + +GList *sensors_applet_plugin_init(void) { + return netbsd_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return netbsd_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/netbsd/netbsd-plugin.h b/sensors-applet/plugins/netbsd/netbsd-plugin.h new file mode 100644 index 00000000..275ae608 --- /dev/null +++ b/sensors-applet/plugins/netbsd/netbsd-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018 Jared McNeill <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NETBSD_PLUGIN_H +#define NETBSD_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* NETBSD_PLUGIN_H */ diff --git a/sensors-applet/plugins/nvidia/Makefile.am b/sensors-applet/plugins/nvidia/Makefile.am new file mode 100644 index 00000000..329897be --- /dev/null +++ b/sensors-applet/plugins/nvidia/Makefile.am @@ -0,0 +1,25 @@ +# NVIDIA plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(NVIDIA_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libnvidia.la + +libnvidia_la_SOURCES = \ + nvidia-plugin.h \ + nvidia-plugin.c + +libnvidia_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) $(NVIDIA_LIBS) +libnvidia_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/nvidia/nvidia-plugin.c b/sensors-applet/plugins/nvidia/nvidia-plugin.c new file mode 100644 index 00000000..2643a2a6 --- /dev/null +++ b/sensors-applet/plugins/nvidia/nvidia-plugin.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2006 Sven Peter <[email protected]> + * Copyright (C) 2006 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <X11/Xlib.h> +#include <NVCtrl/NVCtrl.h> +#include <NVCtrl/NVCtrlLib.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include "nvidia-plugin.h" + +const gchar *plugin_name = "nvidia"; + +#define THERMAL_SENSOR_TEMP "SensorTemp" +#define THERMAL_COOLER_LEVEL "CoolerLevel" +#define GPU_CORE_TEMP "CoreTemp" +#define AMBIENT_TEMP "AmbientTemp" + +/* global variables */ +Display *nvidia_sensors_dpy; /* the connection to the X server */ + +/* returns the value of the sensor */ +static gdouble nvidia_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + Bool res; + int temp; + int i; + + i = g_ascii_strtoll(id + strlen("GPU"), NULL, 10); + if (g_ascii_strcasecmp(path, THERMAL_SENSOR_TEMP) == 0) { + res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_THERMAL_SENSOR, + i, + 0, + NV_CTRL_THERMAL_SENSOR_READING, + &temp); + + } else if (g_ascii_strcasecmp(path, THERMAL_COOLER_LEVEL) == 0) { + res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_COOLER, + i, + 0, + NV_CTRL_THERMAL_COOLER_LEVEL, + &temp); + + } else if (g_ascii_strcasecmp(path, GPU_CORE_TEMP) == 0) { + res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_GPU, + i, + 0, + NV_CTRL_GPU_CORE_TEMPERATURE, + &temp); + + } else if (g_ascii_strcasecmp(path, AMBIENT_TEMP) == 0) { + res = XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_GPU, + i, + 0, + NV_CTRL_AMBIENT_TEMPERATURE, + &temp); + + } else { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, 0, "Invalid path string passed to nvidia_plugin_get_sensor_value"); + return 0; + } + + if (res != True) { + /* when res isn't true something went wrong */ + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, 0, "XNVCTRLQueryAttribute returned false"); + return 0; + } + + /* convert the int to gdouble and return it */ + return (gdouble)temp; +} + +/* creates the connection to the X server and checks whether the + * NV-CONTROL extension is loaded */ +static GList *nvidia_plugin_init(void) { + int dummy; + int event_base, error_base; + GList *sensors = NULL; + + /* create the connection to the X server */ + if (!(nvidia_sensors_dpy = XOpenDisplay(NULL))) { + /* no connection to the X server avaible */ + return sensors; + } + + /* check if the NV-CONTROL extension is available on this X + * server - if so add the two sensors if they exist */ + if (XNVCTRLQueryExtension(nvidia_sensors_dpy, &event_base, &error_base)) { + int i, cnt; + + if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_THERMAL_SENSOR, + &cnt)) { + + for (i = 0; i < cnt; i++) { + gchar *id = g_strdup_printf("GPU%d%s", i, THERMAL_SENSOR_TEMP); + + sensors_applet_plugin_add_sensor(&sensors, + THERMAL_SENSOR_TEMP, + id, + _("GPU"), + TEMP_SENSOR, + TRUE, + GPU_ICON, + DEFAULT_GRAPH_COLOR); + + g_free(id); + } + } + + if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_COOLER, + &cnt)) { + + for (i = 0; i < cnt; i++) { + gchar *id = g_strdup_printf("GPU%d%s", i, THERMAL_COOLER_LEVEL); + + sensors_applet_plugin_add_sensor(&sensors, + THERMAL_COOLER_LEVEL, + id, + _("GPU"), + FAN_SENSOR, + TRUE, + FAN_ICON, + DEFAULT_GRAPH_COLOR); + + g_free(id); + } + } + + if (XNVCTRLQueryTargetCount(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_GPU, + &cnt)) { + + for (i = 0; i < cnt; i++) { + if (XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_GPU, + i, + 0, NV_CTRL_GPU_CORE_TEMPERATURE, &dummy)) { + + gchar *id = g_strdup_printf("GPU%d%s", i, GPU_CORE_TEMP); + + sensors_applet_plugin_add_sensor(&sensors, + GPU_CORE_TEMP, + id, + _("GPU"), + TEMP_SENSOR, + TRUE, + GPU_ICON, + DEFAULT_GRAPH_COLOR); + g_free(id); + } + + if (XNVCTRLQueryTargetAttribute(nvidia_sensors_dpy, + NV_CTRL_TARGET_TYPE_GPU, + i, + 0, NV_CTRL_AMBIENT_TEMPERATURE, &dummy)) { + gchar *id = g_strdup_printf("GPU%d%s", i, AMBIENT_TEMP); + + sensors_applet_plugin_add_sensor(&sensors, + AMBIENT_TEMP, + id, + _("Ambient"), + TEMP_SENSOR, + FALSE, + GENERIC_ICON, + DEFAULT_GRAPH_COLOR); + g_free(id); + } + } + } + + } + return sensors; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return nvidia_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return nvidia_plugin_get_sensor_value(path, id, type, error); +} + diff --git a/sensors-applet/plugins/nvidia/nvidia-plugin.h b/sensors-applet/plugins/nvidia/nvidia-plugin.h new file mode 100644 index 00000000..68d8f013 --- /dev/null +++ b/sensors-applet/plugins/nvidia/nvidia-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006 Sven Peter <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NVIDIA_PLUGIN_H +#define NVIDIA_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* NVIDIA_PLUGIN_H*/ diff --git a/sensors-applet/plugins/omnibook/Makefile.am b/sensors-applet/plugins/omnibook/Makefile.am new file mode 100644 index 00000000..08c96962 --- /dev/null +++ b/sensors-applet/plugins/omnibook/Makefile.am @@ -0,0 +1,24 @@ +# OMNIBOOK plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libomnibook.la + +libomnibook_la_SOURCES = \ + omnibook-plugin.h \ + omnibook-plugin.c + +libomnibook_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libomnibook_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/omnibook/omnibook-plugin.c b/sensors-applet/plugins/omnibook/omnibook-plugin.c new file mode 100644 index 00000000..7728110a --- /dev/null +++ b/sensors-applet/plugins/omnibook/omnibook-plugin.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "omnibook-plugin.h" + +const gchar *plugin_name = "omnibook"; + +#define OMNIBOOK_DEVICE_FILE "/proc/omnibook/temperature" + +enum { + OMNIBOOK_DEVICE_FILE_OPEN_ERROR, + OMNIBOOK_DEVICE_FILE_READ_ERROR +}; + +static void omnibook_plugin_setup_manually(GList **sensors) { + /* omnibook only has the one device file with one temp in it */ + if (g_file_test(OMNIBOOK_DEVICE_FILE, G_FILE_TEST_EXISTS)) { + + sensors_applet_plugin_add_sensor(sensors, + OMNIBOOK_DEVICE_FILE, + _("temperature"), + _("CPU"), + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + } +} + +/* to be called to setup for sys sensors */ +static GList *omnibook_plugin_init(void) { + GList *sensors = NULL; + /* call function to recursively look for sensors starting at the defined base directory */ + omnibook_plugin_setup_manually(&sensors); + + return sensors; +} + +static gdouble omnibook_plugin_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; + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, OMNIBOOK_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + + if (fscanf(fp, "CPU temperature: %f", &sensor_value) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, OMNIBOOK_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + + fclose(fp); + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return omnibook_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return omnibook_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/omnibook/omnibook-plugin.h b/sensors-applet/plugins/omnibook/omnibook-plugin.h new file mode 100644 index 00000000..179f2363 --- /dev/null +++ b/sensors-applet/plugins/omnibook/omnibook-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef OMNIBOOK_PLUGIN_H +#define OMNIBOOK_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* OMNIBOOK_PLUGIN_H*/ diff --git a/sensors-applet/plugins/pmu-sys/Makefile.am b/sensors-applet/plugins/pmu-sys/Makefile.am new file mode 100644 index 00000000..9ef7621b --- /dev/null +++ b/sensors-applet/plugins/pmu-sys/Makefile.am @@ -0,0 +1,24 @@ +# PMU-SYS plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libpmu-sys.la + +libpmu_sys_la_SOURCES = \ + pmu-sys-plugin.h \ + pmu-sys-plugin.c + +libpmu_sys_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libpmu_sys_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.c b/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.c new file mode 100644 index 00000000..6b507423 --- /dev/null +++ b/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "pmu-sys-plugin.h" + +const gchar *plugin_name = "pmu-sys"; + +#define PMU_SYS_BASE_DIR "/sys/devices/temperatures/" +#define PMU_WT_SYS_BASE_DIR "/sys/devices/temperature/" + +#define SENSOR1 "sensor1" +#define CPU "cpu" +#define SENSOR2 "sensor2" +#define GPU "gpu" +#define CASE "case" +#define TEMPERATURE "_temperature" +#define FAN_SPEED "_fan_speed" + +enum { + PMU_SYS_DEVICE_FILE_OPEN_ERROR, + PMU_SYS_DEVICE_FILE_READ_ERROR +}; + +static void pmu_sys_plugin_add_sensor(GList **sensors, const gchar *path) { + gchar *filename; + gchar *label = NULL; + gboolean enable; + SensorType sensor_type; + IconType icon_type = GENERIC_ICON; + + 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_type = 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_type = GPU_ICON; + } else if (g_ascii_strcasecmp(filename, CASE TEMPERATURE) == 0) { + label = g_strdup(_("CASE")); + sensor_type = TEMP_SENSOR; + enable = TRUE; + icon_type = CASE_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_type = FAN_ICON; + } else { + /* disable all other sensors */ + enable = FALSE; + } + + /* only add these 3 sensors */ + if (enable) { + sensors_applet_plugin_add_sensor(sensors, + path, + filename, + label, + sensor_type, + enable, + icon_type, + DEFAULT_GRAPH_COLOR); + + } + + g_free(filename); + g_free(label); +} + +static void pmu_sys_plugin_test_sensor(GList **sensors, const gchar *path) { + gchar *filename; + filename = g_path_get_basename(path); + if (g_ascii_strcasecmp(filename, SENSOR1 TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, SENSOR2 TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, SENSOR1 FAN_SPEED) == 0 || + g_ascii_strcasecmp(filename, CPU TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, GPU TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, CASE TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, CPU FAN_SPEED) == 0) { + + pmu_sys_plugin_add_sensor(sensors, path); + } + + g_free(filename); +} + +/* to be called to setup for sys sensors */ +static +GList *pmu_sys_plugin_init(void) { + GList *sensors = NULL; + /* call function to recursively look for sensors + starting at the defined base directory */ + sensors_applet_plugin_find_sensors(&sensors, PMU_SYS_BASE_DIR, pmu_sys_plugin_test_sensor); + sensors_applet_plugin_find_sensors(&sensors, PMU_WT_SYS_BASE_DIR, pmu_sys_plugin_test_sensor); + return sensors; +} + +/* returns the value of the sensor_list at the given iter, or if an + error occurs, instatiates error with an error message */ +static +gdouble pmu_sys_plugin_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, SENSORS_APPLET_PLUGIN_ERROR, PMU_SYS_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + switch(type) { + case FAN_SENSOR: + if (fscanf(fp, "%f (%f rpm)", &dummy, &sensor_value) != 2) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, PMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + break; + + case TEMP_SENSOR: + if (fscanf(fp, "%f", &sensor_value) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, PMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + break; + + default: + /* should only have added temp or fan sensors */ + g_error("Unknown sensor type passed as parameter to pmu-sys sensor interface, cannot get value for this sensor"); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, PMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + + } + fclose(fp); + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return pmu_sys_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return pmu_sys_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.h b/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.h new file mode 100644 index 00000000..39aee14c --- /dev/null +++ b/sensors-applet/plugins/pmu-sys/pmu-sys-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PMU_SYS_PLUGIN_H +#define PMU_SYS_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* PMU_SYS_PLUGIN_H*/ diff --git a/sensors-applet/plugins/smu-sys/Makefile.am b/sensors-applet/plugins/smu-sys/Makefile.am new file mode 100644 index 00000000..4cf93c4c --- /dev/null +++ b/sensors-applet/plugins/smu-sys/Makefile.am @@ -0,0 +1,24 @@ +# SMU-SYS plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libsmu-sys.la + +libsmu_sys_la_SOURCES = \ + smu-sys-plugin.h \ + smu-sys-plugin.c + +libsmu_sys_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libsmu_sys_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/smu-sys/smu-sys-plugin.c b/sensors-applet/plugins/smu-sys/smu-sys-plugin.c new file mode 100644 index 00000000..f2c93eaa --- /dev/null +++ b/sensors-applet/plugins/smu-sys/smu-sys-plugin.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <glib.h> +#include <glib/gi18n.h> +#include "smu-sys-plugin.h" + +const gchar *plugin_name = "smu-sys"; + +#define SMU_SYS_BASE_DIR "/sys/devices/platform/windfarm.0" + +#define SENSOR1 "sensor1" +#define CPU "cpu" +#define SENSOR2 "sensor2" +#define GPU "gpu" +#define TEMPERATURE "-temp" +#define FAN_SPEED "-fan" + +enum { + SMU_SYS_DEVICE_FILE_OPEN_ERROR, + SMU_SYS_DEVICE_FILE_READ_ERROR +}; + +static void smu_sys_plugin_add_sensor(GList **sensors, const gchar *path) { + gchar *filename; + gchar *label = NULL; + gboolean enable; + SensorType sensor_type; + IconType icon_type = GENERIC_ICON; + + 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_type = 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_type = 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_type = FAN_ICON; + } else { + /* disable all other sensors */ + enable = FALSE; + } + + /* only add these 3 sensors */ + if (enable) { + sensors_applet_plugin_add_sensor(sensors, + path, + filename, + label, + sensor_type, + enable, + icon_type, + DEFAULT_GRAPH_COLOR); + + } + + g_free(filename); + g_free(label); +} + +static void smu_sys_plugin_test_sensor(GList **sensors, const gchar *path) { + gchar *filename; + + filename = g_path_get_basename(path); + if (g_ascii_strcasecmp(filename, SENSOR1 TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, SENSOR2 TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, SENSOR1 FAN_SPEED) == 0 || + g_ascii_strcasecmp(filename, CPU TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, GPU TEMPERATURE) == 0 || + g_ascii_strcasecmp(filename, CPU FAN_SPEED) == 0) { + + smu_sys_plugin_add_sensor(sensors, path); + } + g_free(filename); +} + +/* to be called to setup for sys sensors */ +static GList *smu_sys_plugin_init(void) { + GList *sensors = NULL; + + /* call function to recursively look for sensors + starting at the defined base directory */ + sensors_applet_plugin_find_sensors(&sensors, SMU_SYS_BASE_DIR, smu_sys_plugin_test_sensor); + + return sensors; +} + +/* returns the value of the sensor_list at the given iter, or if an + error occurs, instatiates error with an error message */ +static +gdouble smu_sys_plugin_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.0; + + if (NULL == (fp = fopen(path, "r"))) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SMU_SYS_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path); + return -1.0; + } + switch(type) { + case FAN_SENSOR: + if (fscanf(fp, "%f", &sensor_value) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + break; + + case TEMP_SENSOR: + if (fscanf(fp, "%f", &sensor_value) != 1) { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + fclose(fp); + return -1.0; + } + break; + + default: + /* should only have added temp or fan sensors */ + g_error("Unknown sensor type passed as parameter to smu-sys sensor interface, cannot get value for this sensor"); + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SMU_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } + fclose(fp); + + return (gdouble)sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return smu_sys_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return smu_sys_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/smu-sys/smu-sys-plugin.h b/sensors-applet/plugins/smu-sys/smu-sys-plugin.h new file mode 100644 index 00000000..f3d068cb --- /dev/null +++ b/sensors-applet/plugins/smu-sys/smu-sys-plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SMU_SYS_PLUGIN_H +#define SMU_SYS_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* SMU_SYS_PLUGIN_H */ diff --git a/sensors-applet/plugins/sonypi/Makefile.am b/sensors-applet/plugins/sonypi/Makefile.am new file mode 100644 index 00000000..844f0f69 --- /dev/null +++ b/sensors-applet/plugins/sonypi/Makefile.am @@ -0,0 +1,24 @@ +# SONYPI plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libsonypi.la + +libsonypi_la_SOURCES = \ + sonypi-plugin.h \ + sonypi-plugin.c + +libsonypi_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) +libsonypi_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/sonypi/sonypi-plugin.c b/sensors-applet/plugins/sonypi/sonypi-plugin.c new file mode 100644 index 00000000..64a0c8c1 --- /dev/null +++ b/sensors-applet/plugins/sonypi/sonypi-plugin.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2006-2008 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif /* HAVE_FCNTL_H */ + +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif /* HAVE_SYS_IOCTL_H */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#include <glib.h> +#include <glib/gi18n.h> +#include "sonypi-plugin.h" + +#include <stdint.h> + +const gchar *plugin_name = "sonypi"; + +/* These values are taken from spicctrl by Stelian Pop */ +#define SONYPI_DEV "/dev/sonypi" +#define SONYPI_IOCGFAN _IOR('v', 10, uint8_t) +#define SONYPI_IOCGTEMP _IOR('v', 12, uint8_t) +#define SONYPI_TEMP "sonypi_temp" + +enum { + SONYPI_DEVICE_FILE_OPEN_ERROR, + SONYPI_DEVICE_FILE_READ_ERROR +}; + +static +GList *sonypi_plugin_init(void) { + int fd; + GList *sensors = NULL; + + if ( (fd = open(SONYPI_DEV, O_RDONLY)) != -1 ) { + if ( close(fd) != -1 ) { + sensors_applet_plugin_add_sensor(&sensors, + SONYPI_DEV, + SONYPI_TEMP, + _("CPU TEMP"), + TEMP_SENSOR, + TRUE, + CPU_ICON, + DEFAULT_GRAPH_COLOR); + } + } + return sensors; +} + +static +gdouble sonypi_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + int fd; + guint8 value8; + + gdouble sensor_value = -1.0; + + if ((fd = open(path, O_RDONLY)) != -1) { + /* only use temp sensor */ + if (g_ascii_strcasecmp(id, SONYPI_TEMP) == 0) { + if (ioctl(fd, SONYPI_IOCGTEMP, &value8) != -1) { + sensor_value = (gdouble)value8; + } else { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SONYPI_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path); + } + } + close(fd); + } else { + g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, SONYPI_DEVICE_FILE_OPEN_ERROR, "Error opening from sensor device file %s", path); + } + + return sensor_value; +} + +const gchar *sensors_applet_plugin_name(void) +{ + return plugin_name; +} + +GList *sensors_applet_plugin_init(void) +{ + return sonypi_plugin_init(); +} + +gdouble sensors_applet_plugin_get_sensor_value(const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return sonypi_plugin_get_sensor_value(path, id, type, error); +} diff --git a/sensors-applet/plugins/sonypi/sonypi-plugin.h b/sensors-applet/plugins/sonypi/sonypi-plugin.h new file mode 100644 index 00000000..6b9776d0 --- /dev/null +++ b/sensors-applet/plugins/sonypi/sonypi-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006 Thanate Dhirasakdanon <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SONYPI_PLUGIN_H +#define SONYPI_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* SONYPI_PLUGIN_H*/ diff --git a/sensors-applet/plugins/udisks2/Makefile.am b/sensors-applet/plugins/udisks2/Makefile.am new file mode 100644 index 00000000..b6d911c0 --- /dev/null +++ b/sensors-applet/plugins/udisks2/Makefile.am @@ -0,0 +1,25 @@ +# UDisks2 plugin +plugindir = $(libdir)/mate-sensors-applet/plugins + +AM_CPPFLAGS = -DMATELOCALEDIR=\""$(datadir)/locale/"\" \ + -DG_LOG_DOMAIN=\""sensors-applet"\" \ + -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + -I$(top_srcdir)/sensors-applet \ + $(GLIB_CFLAGS) \ + $(WARN_CFLAGS) + +plugin_LTLIBRARIES = libudisks2.la + +libudisks2_la_SOURCES = \ + udisks2-plugin.h \ + udisks2-plugin.c + +libudisks2_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(GLIB_LIBS) + +libudisks2_la_LIBADD = $(top_builddir)/sensors-applet/lib/libmate-sensors-applet-plugin.la + +-include $(top_srcdir)/git.mk diff --git a/sensors-applet/plugins/udisks2/udisks2-plugin.c b/sensors-applet/plugins/udisks2/udisks2-plugin.c new file mode 100644 index 00000000..7149babb --- /dev/null +++ b/sensors-applet/plugins/udisks2/udisks2-plugin.c @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2017 info-cppsp <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* +Udisks2 plugin for the mate-sensors-applet + +written using the structure and code of the previous version +from Pramod Dematagoda <[email protected]> + +dbus-glib documentation +https://dbus.freedesktop.org/doc/dbus-glib/ +GDBUS documentation +https://developer.gnome.org/gio/stable/index.html + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <gio/gio.h> +#include "udisks2-plugin.h" + +/* remove // from next line for syslog debug */ +//#define UD2PD 1 + +#ifdef UD2PD +#include <syslog.h> +#endif + +#define UDISKS2_BUS_NAME "org.freedesktop.UDisks2" +#define UDISKS2_INTERFACE_NAME "org.freedesktop.DBus.ObjectManager" +#define UDISKS2_DEVICE_INTERFACE_NAME "org.freedesktop.UDisks2.Drive" +#define UDISKS2_DEVICE_INTERFACE2_NAME "org.freedesktop.UDisks2.Drive.Ata" + +#define UDISKS2_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#define UDISKS2_OBJECT_PATH "/org/freedesktop/UDisks2" + +/* Info about a single sensor */ +typedef struct _DevInfo { + gchar *path; + gchar *id; + gdouble temp; + GDBusProxy *sensor_proxy; /* dbus object */ + GError *error; +} DevInfo; + +const gchar *plugin_name = "udisks2"; + +/* a container for the devices found to have smart enabled */ +GHashTable *devices = NULL; + +/* This is a global variable for convenience */ +GDBusConnection *connection = NULL; + +static void update_device (DevInfo *info) { + GError *error = NULL; + GVariant *tempgvar = NULL; + GVariant *tempgvar2 = NULL; + gdouble temp; + + /* check valid input parameter */ + g_return_if_fail (info != NULL); + + /* check connection too */ + g_return_if_fail (connection != NULL); + + g_clear_error (&info->error); + + /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo + * this is used to get the temp value the direct way */ + if (NULL == info->sensor_proxy) { + info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_BUS_NAME, + info->path, + UDISKS2_PROPERTIES_INTERFACE, + NULL, &error); + + /* check, just to be sure */ + if (NULL == info->sensor_proxy) { + +#ifdef UD2PD +syslog(LOG_ERR, "Failed to get drive temperature 1"); +#endif + g_debug ("Failed to get drive temperature 1: %s", error->message); + g_clear_error (&error); + return; + } + } + +/* note on timing: + * it seems to me that smart updates occur automatically every 10 minutes + * mate-sensor-applet has a default refresh of 2 seconds... + * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */ + + /* directly asking the device's DBus object for the temp */ + tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get", + g_variant_new ("(ss)", + UDISKS2_DEVICE_INTERFACE2_NAME, + "SmartTemperature"), /* parameters */ + G_DBUS_CALL_FLAGS_NONE, /* flags */ + -1, /* timeout */ + NULL, /* cancellable */ + &error); + + if (NULL == tempgvar) { + +#ifdef UD2PD +syslog(LOG_ERR, "Failed to get drive temperature 2"); +#endif + g_debug ("Failed to get drive temperature 2: %s", error->message); + g_clear_error (&error); + /* throw away proxy, maybe next time it will be better */ + g_clear_object (&info->sensor_proxy); + return; + + } else { + +#ifdef UD2PD +syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE)); +/* leaks memory! */ +//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE)); +#endif + + /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble)) + * hence unpacking + * need to free up every param / return value, so can't do it like: + * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */ + tempgvar2 = g_variant_get_child_value (tempgvar, 0); + g_variant_unref (tempgvar); + tempgvar = g_variant_get_variant (tempgvar2); + g_variant_unref (tempgvar2); + temp = g_variant_get_double (tempgvar); + g_variant_unref (tempgvar); + + /* temp in K */ + info->temp = temp - 273.15; + +#ifdef UD2PD +syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp); +#endif + + } + +} + +/* in this function we would like to get a list of device (hdd/ssd) paths + * then with each path we get the temperature + * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it + * maybe a better version would be to use GDBusObjectManager Server + Client ?? */ +static void udisks2_plugin_get_sensors (GList **sensors) { + +#ifdef UD2PD +syslog(LOG_ERR, "fstart"); +#endif + + GDBusProxy *proxy = NULL; + GError *error = NULL; + + DevInfo *info; + + /* This connection will be used for everything, including the obtaining of sensor data */ + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + +#ifdef UD2PD +syslog(LOG_ERR, "dbus conn fail"); +#endif + + g_debug ("Failed to open connection to DBUS: %s", error->message); + g_clear_error (&error); + return; + } + +#ifdef UD2PD +syslog(LOG_ERR, "dbus conn success"); +#endif + + /* I use this proxy to get all info of all devices at once */ + proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_BUS_NAME, + UDISKS2_OBJECT_PATH, + UDISKS2_INTERFACE_NAME, + NULL, &error); + + if (NULL == proxy) { + +#ifdef UD2PD +syslog(LOG_ERR, "dbus conn proxy fail"); +#endif + g_debug ("dbus conn proxy fail: %s", error->message); + g_clear_error (&error); + g_clear_object (&connection); + return; + } + +#ifdef UD2PD +syslog(LOG_ERR, "dbus conn proxy success"); +#endif + + /* The object paths of the disks are enumerated and placed in an array of object paths + * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */ + + /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise + * need second variable to prevent memory leak */ + GVariant *managed_objects = NULL; + GVariant *managed_objects2 = NULL; + + managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects", + NULL, /* parameters */ + G_DBUS_CALL_FLAGS_NONE, /* flags */ + -1, /* timeout */ + NULL, /* cancellable */ + &error); + + if (NULL == managed_objects2) { + +#ifdef UD2PD +syslog(LOG_ERR, "Failed to enumerate disk devices"); +#endif + + g_debug ("Failed to enumerate disk devices: %s", error->message); + g_clear_error (&error); + g_clear_object (&proxy); + g_clear_object (&connection); + return; + } + + /* the result dictionary is enclosed in an array, unpack */ + managed_objects = g_variant_get_child_value (managed_objects2, 0); + g_variant_unref (managed_objects2); + +#ifdef UD2PD +//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE)); +syslog(LOG_ERR, "success to enumerate disk devices"); +#endif + + /* iterator for the result dictionary + * iterator code is based on the g_variant_iter_next() documentation + * iter is freed if the GVariant is, when using g_variant_iter_init() */ + GVariantIter iter; + gchar *key = NULL; /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */ + GVariant *value = NULL; + +#ifdef UD2PD +/* log collection size */ +syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects)); +#else + g_variant_iter_init (&iter, managed_objects); +#endif + + /* "{sv}" is a GVariant format string + * {} dictionary of, s string, v GVariant + * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}'' + * a is array, o is object path + * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key) + * and get 'everything else' (as a GVariant) into the 2nd variable (value) + * needs the & before the key and value params! */ + while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) { + +#ifdef UD2PD +syslog(LOG_ERR, "in iter while loop"); +syslog(LOG_ERR, "key value: %s", key); +//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE)); +#endif + + /* level 2 + * create a dictionary of value + * the two interface names that we are searching for are known and defined + * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}' + * using general lookup */ + + GVariant *propdict = NULL; /* drive data */ + GVariant *propdict2 = NULL; /* drive smart data */ + + /* make two dictionaries that contain the properties of the drive interfaces */ + propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME, G_VARIANT_TYPE_DICTIONARY); + propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME, G_VARIANT_TYPE_DICTIONARY); + + /* do we have the right ifname keys? */ + if ((NULL != propdict) && (NULL != propdict2)) { + +#ifdef UD2PD +syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE)); +syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE)); +#endif + + /* get data */ + const gchar *id = NULL; + const gchar *model = NULL; + + gboolean smartenabled; + gdouble temp; + + /* NULL, bc we don't care about the length of the string*/ + id = g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING), NULL); + model = g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING), NULL); + + smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN)); + temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE)); + +#ifdef UD2PD +syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id); +syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model); +syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled); +syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp); +#endif + + /* only go on if smart is enabled + * save data */ + if (smartenabled) { + + info = g_new0 (DevInfo, 1); + if (NULL == devices) { + devices = g_hash_table_new (g_str_hash, g_str_equal); + } + + info->id = g_strdup (id); + info->path = g_strdup (key); + + /* temp in K + * this could be left at 0.0, 2 seconds later it will be refreshed anyway */ + info->temp = (gdouble) temp - 273.15; + g_hash_table_insert (devices, info->id, info); + + /* Write the sensor data */ + sensors_applet_plugin_add_sensor (sensors, + id, + "Disk Temperature", + model, + TEMP_SENSOR, + FALSE, + HDD_ICON, + DEFAULT_GRAPH_COLOR); + + g_debug ("Added %s", id); + +#ifdef UD2PD +syslog(LOG_ERR, "Added %s", id); +#endif + + } else { + +#ifdef UD2PD +syslog(LOG_ERR, "No temp data for device: %s\n", key); +#endif + + g_debug ("No temp data for device: %s\n", key); + } + } + +#ifdef UD2PD +syslog(LOG_ERR, "b4 free2"); +#endif + + /* free propdict, propdict2 + * g_variant_dict_unref() may not work a few times, gives error + * this one seems to do fine */ + if (NULL != propdict) {g_variant_unref (propdict);} + if (NULL != propdict2) {g_variant_unref (propdict2);} + +#ifdef UD2PD +syslog(LOG_ERR, "b4 free3"); +#endif + + g_free (key); + g_variant_unref (value); + + } /* end of while loop */ + + g_variant_unref (managed_objects); + g_clear_object (&proxy); + if (NULL == devices) { + g_clear_object (&connection); + } +} + +/* this function is called every refresh cycle */ +static gdouble udisks2_plugin_get_sensor_value (const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + DevInfo *info = NULL; + + /* get device stuct from data store */ + info = (DevInfo *) g_hash_table_lookup (devices, path); + if (NULL == info) { + g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR, 0, "Error finding disk with path %s", path); + return 0.0; + } + + if (info->error) { + *error = info->error; + info->error = NULL; + return 0.0; + } + + /* refresh device temp */ + update_device (info); + return info->temp; +} + +/* API functions */ +const gchar *sensors_applet_plugin_name (void) { + return plugin_name; +} + +static GList *udisks2_plugin_init (void) { + GList *sensors = NULL; + + udisks2_plugin_get_sensors (&sensors); + + return sensors; +} + +GList *sensors_applet_plugin_init (void) { + return udisks2_plugin_init (); +} + +gdouble sensors_applet_plugin_get_sensor_value (const gchar *path, + const gchar *id, + SensorType type, + GError **error) { + + return udisks2_plugin_get_sensor_value (path, id, type, error); +} diff --git a/sensors-applet/plugins/udisks2/udisks2-plugin.h b/sensors-applet/plugins/udisks2/udisks2-plugin.h new file mode 100644 index 00000000..43cf5f61 --- /dev/null +++ b/sensors-applet/plugins/udisks2/udisks2-plugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 info-cppsp <[email protected]> + * Copyright (C) 2005-2009 Alex Murray <[email protected]> + * Copyright (C) 2012-2021 MATE Developers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UDISKS2_PLUGIN_H +#define UDISKS2_PLUGIN_H + +#include <sensors-applet/sensors-applet-plugin.h> + +#endif /* UDISKS2_PLUGIN_H */ |
