Adding upstream version 0.5.4.1.
[debian/lxpanel.git] / src / plugins / thermal / thermal.c
CommitLineData
aa0e9095
DB
1/**
2 * Thermal plugin to lxpanel
3 *
4 * Copyright (C) 2007 by Daniel Kesler <kesler.daniel@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
7486d297
DB
21
22#include <sys/types.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <glib/gi18n.h>
26
27#include <string.h>
28
29#include "panel.h"
30#include "misc.h"
31#include "plugin.h"
32
33#include "dbg.h"
34
35#define THERMAL_DIRECTORY "/proc/acpi/thermal_zone/" /* must be slash-terminated */
36#define THERMAL_TEMPF "temperature"
37#define THERMAL_TRIP "trip_points"
38#define TRIP_CRITICAL "critical (S5):"
39
40typedef struct {
2ba86315 41 Plugin * plugin;
7486d297
DB
42 GtkWidget *main;
43 GtkWidget *namew;
44 GtkTooltips *tip;
45 int critical;
46 int warning1;
47 int warning2;
48 int custom_levels, auto_sensor;
49 char *sensor,
50 *str_cl_normal,
51 *str_cl_warning1,
52 *str_cl_warning2;
53 unsigned int timer;
54 GdkColor cl_normal,
55 cl_warning1,
56 cl_warning2;
57} thermal;
58
7486d297
DB
59static gint
60get_critical(thermal *th){
61 FILE *state;
62 char buf[ 256 ], sstmp [ 100 ];
63 char* pstr;
64
65 if(th->sensor == NULL) return -1;
66
67 sprintf(sstmp,"%s%s",th->sensor,THERMAL_TRIP);
68
69 if (!(state = fopen( sstmp, "r"))) {
70 //printf("cannot open %s\n",sstmp);
71 return -1;
72 }
73
74 while( fgets(buf, 256, state) &&
75 ! ( pstr = strstr(buf, TRIP_CRITICAL) ) );
76 if( pstr )
77 {
78 pstr += strlen(TRIP_CRITICAL);
79 while( *pstr && *pstr == ' ' )
80 ++pstr;
81
82 pstr[strlen(pstr)-3] = '\0';
83 printf("Critical: [%s]\n",pstr);
84 fclose(state);
85 return atoi(pstr);
86 }
87
88 fclose(state);
89 return -1;
90}
91
92static gint
93get_temperature(thermal *th){
94 FILE *state;
95 char buf[ 256 ], sstmp [ 100 ];
96 char* pstr;
97
98 if(th->sensor == NULL) return -1;
99
100 sprintf(sstmp,"%s%s",th->sensor,THERMAL_TEMPF);
101
102 if (!(state = fopen( sstmp, "r"))) {
103 //printf("cannot open %s\n",sstmp);
104 return -1;
105 }
106
107 while( fgets(buf, 256, state) &&
108 ! ( pstr = strstr(buf, "temperature:") ) );
109 if( pstr )
110 {
111 pstr += 12;
112 while( *pstr && *pstr == ' ' )
113 ++pstr;
114
115 pstr[strlen(pstr)-3] = '\0';
116 fclose(state);
117 return atoi(pstr);
118 }
119
120 fclose(state);
121 return -1;
122}
123
124static gint
125update_display(thermal *th)
126{
127 char buffer [60];
128 int n;
129 int temp = get_temperature(th);
130 GdkColor color;
131
132 if(temp >= th->warning2)
133 color = th->cl_warning2;
134 else if(temp >= th->warning1)
135 color = th->cl_warning1;
136 else
137 color = th->cl_normal;
138
139 ENTER;
140 if(temp == -1)
2ba86315 141 panel_draw_label_text(th->plugin->panel, th->namew, "NA", TRUE, TRUE);
7486d297 142 else
2ba86315 143 {
7486d297 144 n = sprintf(buffer, "<span color=\"#%06x\"><b>%02d</b></span>", gcolor2rgb24(&color), temp);
2ba86315
DB
145 gtk_label_set_markup (GTK_LABEL(th->namew), buffer) ;
146 }
7486d297 147
7486d297
DB
148 RET(TRUE);
149}
150
151static void
152check_sensors( thermal* th )
153{
154 GDir *sensorsDirectory;
155 const char *sensor_name;
156 char sensor_path[100];
157
158 if (! (sensorsDirectory = g_dir_open(THERMAL_DIRECTORY, 0, NULL)))
159 {
160 th->sensor = NULL;
161 return;
162 }
163
164 /* Scan the thermal_zone directory for available sensors */
165 while ((sensor_name = g_dir_read_name(sensorsDirectory))) {
166 if (sensor_name[0] != '.') {
167 sprintf(sensor_path,"%s%s/",THERMAL_DIRECTORY, sensor_name);
168 if(th->sensor) {
169 g_free(th->sensor);
170 th->sensor = NULL;
171 }
172 th->sensor = strdup(sensor_path);
173 //printf("sensor: %s\n", b->sensor);
174 break;
175 }
176 }
177 g_dir_close(sensorsDirectory);
178}
179
180static int
181thermal_constructor(Plugin *p, char** fp)
182{
183 thermal *th;
7486d297
DB
184
185 ENTER;
186 th = g_new0(thermal, 1);
2ba86315 187 th->plugin = p;
7486d297
DB
188 p->priv = th;
189
190 p->pwid = gtk_event_box_new();
191 GTK_WIDGET_SET_FLAGS( p->pwid, GTK_NO_WINDOW );
192 gtk_container_set_border_width( GTK_CONTAINER(p->pwid), 2 );
193
194 th->namew = gtk_label_new("ww");
195 gtk_container_add(GTK_CONTAINER(p->pwid), th->namew);
196
aa0e9095 197 th->main = p->pwid;
7486d297
DB
198 th->tip = gtk_tooltips_new();
199
200 g_signal_connect (G_OBJECT (p->pwid), "button_press_event",
2ba86315 201 G_CALLBACK (plugin_button_press_event), (gpointer) p);
7486d297
DB
202
203 line s;
204 s.len = 256;
205
206 if (fp) {
207 /* Apply options */
208 while (lxpanel_get_line(fp, &s) != LINE_BLOCK_END) {
209 if (s.type == LINE_NONE) {
210 ERR( "thermal: illegal token %s\n", s.str);
211 goto error;
212 }
213 if (s.type == LINE_VAR) {
214 if (!g_ascii_strcasecmp(s.t[0], "NormalColor")){
215 th->str_cl_normal = g_strdup(s.t[1]);
216 }else if (!g_ascii_strcasecmp(s.t[0], "Warning1Color")){
217 th->str_cl_warning1 = g_strdup(s.t[1]);
218 }else if (!g_ascii_strcasecmp(s.t[0], "Warning2Color")){
219 th->str_cl_warning2 = g_strdup(s.t[1]);
220 }else if (!g_ascii_strcasecmp(s.t[0], "AutomaticSensor")){
221 th->auto_sensor= atoi(s.t[1]);
222 }else if (!g_ascii_strcasecmp(s.t[0], "CustomLevels")){
223 th->custom_levels= atoi(s.t[1]);
224 }else if (!g_ascii_strcasecmp(s.t[0], "Sensor")){
225 th->sensor= g_strdup(s.t[1]);
226 }else if (!g_ascii_strcasecmp(s.t[0], "Warning1Temp")){
227 th->warning1 = atoi(s.t[1]);
228 }else if (!g_ascii_strcasecmp(s.t[0], "Warning2Temp")){
229 th->warning2 = atoi(s.t[1]);
230 }else {
231 ERR( "thermal: unknown var %s\n", s.t[0]);
7486d297
DB
232 }
233 }
234 else {
235 ERR( "thermal: illegal in this context %s\n", s.str);
236 goto error;
237 }
238 }
239
240 }
241
242 if(!th->str_cl_normal)
243 th->str_cl_normal = g_strdup("#00ff00");
244 if(!th->str_cl_warning1)
245 th->str_cl_warning1 = g_strdup("#fff000");
246 if(!th->str_cl_warning2)
247 th->str_cl_warning2 = g_strdup("#ff0000");
248
249 gdk_color_parse(th->str_cl_normal, &(th->cl_normal));
250 gdk_color_parse(th->str_cl_warning1, &(th->cl_warning1));
251 gdk_color_parse(th->str_cl_warning2, &(th->cl_warning2));
252
253
254 if(th->sensor == NULL) th->auto_sensor = TRUE;
255 if(th->auto_sensor) check_sensors(th);
256
257 th->critical = get_critical(th);
258
259 if(!th->custom_levels){
260 th->warning1 = th->critical - 10;
261 th->warning2 = th->critical - 5;
262 }
263
aa0e9095
DB
264 gtk_widget_show(th->namew);
265
7486d297
DB
266 update_display(th);
267 th->timer = g_timeout_add(1000, (GSourceFunc) update_display, (gpointer)th);
268
269 RET(TRUE);
270
271error:
7486d297
DB
272 RET(FALSE);
273}
274
275static void applyConfig(Plugin* p)
276{
277
278 thermal *th = (thermal *)p->priv;
279
280 ENTER;
281
282 if (th->str_cl_normal) gdk_color_parse(th->str_cl_normal, &th->cl_normal);
283 if (th->str_cl_warning1) gdk_color_parse(th->str_cl_warning1, &th->cl_warning1);
284 if (th->str_cl_warning2) gdk_color_parse(th->str_cl_warning2, &th->cl_warning2);
285
286 if(th->auto_sensor) check_sensors(th);
287
288 if(th->custom_levels){
289 th->warning1 = th->critical - 10;
290 th->warning2 = th->critical - 5;
291 }
292
293 RET();
294}
295
296static void config(Plugin *p, GtkWindow* parent) {
297 ENTER;
298
299 GtkWidget *dialog;
300 thermal *th = (thermal *) p->priv;
301 dialog = create_generic_config_dlg(_(p->class->name),
302 GTK_WIDGET(parent),
303 (GSourceFunc) applyConfig, (gpointer) p,
304 _("Normal"), &th->str_cl_normal, CONF_TYPE_STR,
305 _("Warning1"), &th->str_cl_warning1, CONF_TYPE_STR,
306 _("Warning2"), &th->str_cl_warning2, CONF_TYPE_STR,
307 _("Automatic sensor location"), &th->auto_sensor, CONF_TYPE_BOOL,
308 _("Sensor"), &th->sensor, CONF_TYPE_STR,
309 _("Automatic temperature levels"), &th->custom_levels, CONF_TYPE_BOOL,
310 _("Warning1 Temperature"), &th->warning1, CONF_TYPE_INT,
311 _("Warning2 Temperature"), &th->warning2, CONF_TYPE_INT,
312 NULL);
313 gtk_window_present(GTK_WINDOW(dialog));
314
315 RET();
316}
317
318static void
319thermal_destructor(Plugin *p)
320{
321 thermal *th = (thermal *)p->priv;
322
323 ENTER;
324 th = (thermal *) p->priv;
325 g_free(th->sensor);
326 g_free(th->str_cl_normal);
327 g_free(th->str_cl_warning1);
328 g_free(th->str_cl_warning2);
329 g_source_remove(th->timer);
330 g_free(th);
331 RET();
332}
333
334static void save_config( Plugin* p, FILE* fp )
335{
336 thermal *th = (thermal *)p->priv;
337
338 lxpanel_put_str( fp, "NormalColor", th->str_cl_normal );
339 lxpanel_put_str( fp, "Warning1Color", th->str_cl_warning1 );
340 lxpanel_put_str( fp, "Warning2Color", th->str_cl_warning2 );
341 lxpanel_put_int( fp, "CustomLevels", th->custom_levels );
342 lxpanel_put_int( fp, "Warning1Temp", th->warning1 );
343 lxpanel_put_int( fp, "Warning2Temp", th->warning2 );
344 lxpanel_put_int( fp, "AutomaticSensor", th->auto_sensor );
345 lxpanel_put_str( fp, "Sensor", th->sensor );
346}
347
348PluginClass thermal_plugin_class = {
2ba86315
DB
349
350 PLUGINCLASS_VERSIONING,
7486d297
DB
351
352 type : "thermal",
353 name : N_("Temperature Monitor"),
354 version: "0.6",
aa0e9095 355 description : N_("Display system temperature"),
7486d297
DB
356
357 constructor : thermal_constructor,
358 destructor : thermal_destructor,
359 config : config,
aa0e9095
DB
360 save : save_config,
361 panel_configuration_changed : NULL
7486d297 362};