Bug Summary

File:sensors-applet/active-sensor.c
Warning:line 305, column 15
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name active-sensor.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/sensors-applet -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -D HAVE_CONFIG_H -I . -D CAFELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/cafe-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D UIDIR="/usr/local/share/cafe-sensors-applet/ui" -D SENSORS_APPLET_PLUGIN_DIR="/usr/local/lib/cafe-sensors-applet/plugins" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-panel-4.0/libcafe-panel-applet -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cairo -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/pixman-1 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/libmount -I /usr/include/blkid -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/sensors-applet -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-07-21-115029-79067-1 -x c active-sensor.c
1/*
2 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifdef HAVE_CONFIG_H1
20#include "config.h"
21#endif /* HAVE_CONFIG_H */
22
23#ifdef HAVE_STRING_H1
24#include <string.h>
25#endif /* HAVE_STRING_H */
26
27#include <glib.h>
28#include <glib/gi18n.h>
29#include <ctk/ctk.h>
30#include <gio/gio.h>
31
32#include "active-sensor.h"
33#include "sensors-applet-plugins.h"
34#include "sensors-applet-settings.h"
35
36typedef enum {
37 VERY_LOW_SENSOR_VALUE = 0,
38 LOW_SENSOR_VALUE,
39 NORMAL_SENSOR_VALUE,
40 HIGH_SENSOR_VALUE,
41 VERY_HIGH_SENSOR_VALUE
42} SensorValueRange;
43
44/* Cast a given value to a valid SensorValueRange */
45#define SENSOR_VALUE_RANGE(x)((SensorValueRange)((((x) > (VERY_HIGH_SENSOR_VALUE)) ? (VERY_HIGH_SENSOR_VALUE
) : (((x) < (VERY_LOW_SENSOR_VALUE)) ? (VERY_LOW_SENSOR_VALUE
) : (x)))))
((SensorValueRange)(CLAMP(x, VERY_LOW_SENSOR_VALUE, VERY_HIGH_SENSOR_VALUE)(((x) > (VERY_HIGH_SENSOR_VALUE)) ? (VERY_HIGH_SENSOR_VALUE
) : (((x) < (VERY_LOW_SENSOR_VALUE)) ? (VERY_LOW_SENSOR_VALUE
) : (x)))
))
46
47#define CAIRO_GRAPH_COLOR_GRADIENT0.4 0.4
48
49static const gchar * const temp_overlay_icons[] = {
50 PIXMAPS_DIR"/usr/local/share/pixmaps/cafe-sensors-applet/" "very-low-temp-icon.png",
51 PIXMAPS_DIR"/usr/local/share/pixmaps/cafe-sensors-applet/" "low-temp-icon.png",
52 PIXMAPS_DIR"/usr/local/share/pixmaps/cafe-sensors-applet/" "normal-temp-icon.png",
53 PIXMAPS_DIR"/usr/local/share/pixmaps/cafe-sensors-applet/" "high-temp-icon.png",
54 PIXMAPS_DIR"/usr/local/share/pixmaps/cafe-sensors-applet/" "very-high-temp-icon.png"
55};
56
57
58static gdouble sensor_value_range_normalised(gdouble value,
59 gdouble low_value,
60 gdouble high_value) {
61
62 return ((value - low_value)/(high_value - low_value));
63}
64
65static SensorValueRange sensor_value_range(gdouble sensor_value,
66 gdouble low_value,
67 gdouble high_value) {
68
69 gdouble range;
70 range = sensor_value_range_normalised(sensor_value, low_value, high_value)*(gdouble)(VERY_HIGH_SENSOR_VALUE);
71
72 /* check if need to round up, otherwise let int conversion
73 * round down for us and make sure it is a valid range
74 * value */
75 return SENSOR_VALUE_RANGE(((gint)range + ((range - ((gint)range)) >= 0.5)))((SensorValueRange)((((((gint)range + ((range - ((gint)range)
) >= 0.5))) > (VERY_HIGH_SENSOR_VALUE)) ? (VERY_HIGH_SENSOR_VALUE
) : (((((gint)range + ((range - ((gint)range)) >= 0.5))) <
(VERY_LOW_SENSOR_VALUE)) ? (VERY_LOW_SENSOR_VALUE) : (((gint
)range + ((range - ((gint)range)) >= 0.5)))))))
;
76}
77
78static gboolean active_sensor_execute_alarm(ActiveSensor *active_sensor,
79 NotifType notif_type) {
80
81 gboolean ret;
82 GError *error = NULL((void*)0);
83
84 sensors_applet_notify_active_sensor(active_sensor, notif_type);
85 g_debug("EXECUTING %s ALARM: %s",
86 (notif_type == LOW_ALARM ?
87 "LOW" : "HIGH"),
88 active_sensor->alarm_command[notif_type]);
89 ret = g_spawn_command_line_async (active_sensor->alarm_command[notif_type], &error);
90 g_debug("Command executed in shell");
91
92 if (error)
93 g_error_free (error);
94
95 return ret;
96}
97
98static gboolean active_sensor_execute_low_alarm(ActiveSensor *active_sensor) {
99 return active_sensor_execute_alarm(active_sensor, LOW_ALARM);
100}
101
102static gboolean active_sensor_execute_high_alarm(ActiveSensor *active_sensor) {
103 return active_sensor_execute_alarm(active_sensor, HIGH_ALARM);
104}
105
106/* needs to be able to be called by the config dialog when the alarm command changes */
107void active_sensor_alarm_off(ActiveSensor *active_sensor,
108 NotifType notif_type) {
109
110 g_assert(active_sensor)do { if (active_sensor) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 110, ((const char*) (__func__)), "active_sensor"
); } while (0)
;
111
112 if (active_sensor->alarm_timeout_id[notif_type] != -1) {
113 g_debug("Disabling %s alarm.", (notif_type == LOW_ALARM ? "LOW" : "HIGH"));
114 if (!g_source_remove(active_sensor->alarm_timeout_id[notif_type])) {
115 g_debug("Error removing alarm source");
116 }
117 g_free(active_sensor->alarm_command[notif_type]);
118 active_sensor->alarm_timeout_id[notif_type] = -1;
119
120 }
121 sensors_applet_notify_end(active_sensor, notif_type);
122}
123
124static void active_sensor_all_alarms_off(ActiveSensor *active_sensor) {
125 /* turn off any alarms */
126 int i;
127 for (i = 0; i < NUM_ALARMS2; i++) {
128 if (active_sensor->alarm_timeout_id[i] >= 0) {
129 g_debug("-- turning off notif with type %d ---", i);
130 active_sensor_alarm_off(active_sensor, i);
131 }
132 }
133}
134
135static void active_sensor_alarm_on(ActiveSensor *active_sensor,
136 NotifType notif_type) {
137
138 CtkTreeModel *model;
139 CtkTreePath *tree_path;
140 CtkTreeIter iter;
141
142 g_assert(active_sensor)do { if (active_sensor) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 142, ((const char*) (__func__)), "active_sensor"
); } while (0)
;
143
144 model = ctk_tree_row_reference_get_model(active_sensor->sensor_row);
145 tree_path = ctk_tree_row_reference_get_path(active_sensor->sensor_row);
146
147 if (ctk_tree_model_get_iter(model, &iter, tree_path)) {
148
149 if (active_sensor->alarm_timeout_id[notif_type] == -1) {
150 /* alarm is not currently on */
151 ctk_tree_model_get(model,
152 &iter,
153 (notif_type == LOW_ALARM ?
154 LOW_ALARM_COMMAND_COLUMN :
155 HIGH_ALARM_COMMAND_COLUMN),
156 &(active_sensor->alarm_command[notif_type]),
157 ALARM_TIMEOUT_COLUMN, &(active_sensor->alarm_timeout),
158 -1);
159
160 g_debug("Activating alarm to repeat every %d seconds", active_sensor->alarm_timeout);
161
162 /* execute alarm once, then add to time to keep repeating it */
163 active_sensor_execute_alarm(active_sensor, notif_type);
164 int timeout = (active_sensor->alarm_timeout <= 0 ? G_MAXINT2147483647 : active_sensor->alarm_timeout);
165 switch (notif_type) {
166 case LOW_ALARM:
167 active_sensor->alarm_timeout_id[notif_type] = g_timeout_add_seconds(timeout,
168 (GSourceFunc)active_sensor_execute_low_alarm,
169 active_sensor);
170 break;
171
172 case HIGH_ALARM:
173 active_sensor->alarm_timeout_id[notif_type] = g_timeout_add_seconds(timeout,
174 (GSourceFunc)active_sensor_execute_high_alarm,
175 active_sensor);
176 break;
177
178 default:
179 g_debug("Unknown notif type: %d", notif_type);
180 }
181
182 }
183 }
184
185 ctk_tree_path_free(tree_path);
186}
187
188/**
189 * Compares two ActiveSensors and returns -1 if a comes before b in the tree,
190 * 0 if refer to same row, 1 if b comes before a
191 */
192gint active_sensor_compare(ActiveSensor *a, ActiveSensor *b) {
193 CtkTreePath *a_tree_path, *b_tree_path;
194 gint ret_val;
195
196 g_assert(a)do { if (a) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 196, ((const char*) (__func__)), "a"); }
while (0)
;
197 g_assert(b)do { if (b) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 197, ((const char*) (__func__)), "b"); }
while (0)
;
198
199 a_tree_path = ctk_tree_row_reference_get_path(a->sensor_row);
200 b_tree_path = ctk_tree_row_reference_get_path(b->sensor_row);
201
202 ret_val = ctk_tree_path_compare(a_tree_path, b_tree_path);
203
204 ctk_tree_path_free(a_tree_path);
205 ctk_tree_path_free(b_tree_path);
206
207 return ret_val;
208}
209
210static void active_sensor_update_icon(ActiveSensor *active_sensor,
211 GdkPixbuf *base_icon,
212 SensorType sensor_type) {
213
214 GdkPixbuf *overlay_icon, *new_icon;
215 const gchar *overlay_icon_filename = NULL((void*)0);
216 SensorValueRange value_range;
217
218 g_assert(active_sensor)do { if (active_sensor) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 218, ((const char*) (__func__)), "active_sensor"
); } while (0)
;
219
220 /* select overlay icon depending on sensor value */
221 value_range = sensor_value_range(active_sensor->sensor_values[0],
222 active_sensor->sensor_low_value,
223 active_sensor->sensor_high_value);
224
225 if (sensor_type == TEMP_SENSOR) {
226 overlay_icon_filename = temp_overlay_icons[value_range];
227 }
228
229 /* load base icon */
230 new_icon = gdk_pixbuf_copy(base_icon);
231
232 /* only load overlay if required */
233 if (overlay_icon_filename) {
234 overlay_icon = gdk_pixbuf_new_from_file_at_size(overlay_icon_filename,
235 DEFAULT_ICON_SIZE22,
236 DEFAULT_ICON_SIZE22,
237 NULL((void*)0));
238
239 if (overlay_icon) {
240 gdk_pixbuf_composite(overlay_icon, new_icon,
241 0, 0,
242 DEFAULT_ICON_SIZE22, DEFAULT_ICON_SIZE22,
243 0, 0,
244 1.0, 1.0,
245 GDK_INTERP_BILINEAR,
246 255);
247
248 g_object_unref(overlay_icon);
249 }
250 }
251
252 ctk_image_set_from_pixbuf(CTK_IMAGE(active_sensor->icon)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->icon)), ((ctk_image_get_type ()))))))
,
253 new_icon);
254 g_object_unref(new_icon);
255
256}
257
258static void active_sensor_update_graph(ActiveSensor *as, cairo_t *cr) {
259 CtkAllocation allocation;
260 gdouble line_height;
261 gdouble width, height;
262 gdouble x, y;
2
'x' declared without an initial value
263 cairo_pattern_t *pattern;
264 gint i;
265
266 ctk_widget_get_allocation (as->graph, &allocation);
267 width = allocation.width;
268 height = allocation.height;
269
270 /* so we can set a clipping area, as well as fill the * back of the graph black */
271 cairo_rectangle(cr,
272 0, 0,
273 width,
274 height);
275 /* clip to rectangle and keep it as a path so can be
276 * filled below */
277 cairo_clip_preserve(cr);
278
279 /* use black for bg color of graphs */
280 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
281 cairo_fill(cr);
282
283 /* determine height to scale line at for each value -
284 * only do as many as will fit or the number of
285 * samples that we have */
286 for (i = 0; i < MIN(as->num_samples, width)(((as->num_samples) < (width)) ? (as->num_samples) :
(width))
; i++) {
3
Assuming 'width' is <= field 'num_samples'
4
'?' condition is false
5
Loop condition is false. Execution continues on line 305
287 /* need to remove one more to make it line up
288 * properly when drawing */
289 x = width - i - 1;
290 y = height;
291
292 line_height = sensor_value_range_normalised(as->sensor_values[i],
293 as->sensor_low_value,
294 as->sensor_high_value) * height;
295
296 if (line_height > 0) {
297 cairo_move_to(cr, x, y);
298 cairo_line_to(cr, x, y - line_height);
299 }
300 }
301
302 /* make lines a gradient from slightly darker than
303 * chosen color at bottom of graph, to slightly
304 * lighter than chosen color at top of graph */
305 pattern = cairo_pattern_create_linear(x, y, x, 0);
6
1st function call argument is an uninitialized value
306 cairo_pattern_add_color_stop_rgb(pattern,
307 0,
308 as->graph_color.red - CAIRO_GRAPH_COLOR_GRADIENT0.4,
309 as->graph_color.green - CAIRO_GRAPH_COLOR_GRADIENT0.4,
310 as->graph_color.blue - CAIRO_GRAPH_COLOR_GRADIENT0.4);
311
312 cairo_pattern_add_color_stop_rgb(pattern,
313 height,
314 as->graph_color.red + CAIRO_GRAPH_COLOR_GRADIENT0.4,
315 as->graph_color.green + CAIRO_GRAPH_COLOR_GRADIENT0.4,
316 as->graph_color.blue + CAIRO_GRAPH_COLOR_GRADIENT0.4);
317
318 cairo_set_source(cr, pattern);
319 cairo_stroke(cr);
320 cairo_pattern_destroy(pattern);
321}
322
323void active_sensor_destroy(ActiveSensor *active_sensor) {
324 g_debug("-- destroying active sensor label...");
325 ctk_widget_destroy(active_sensor->label);
326
327 g_debug("-- destroying active sensor icon..");
328 ctk_widget_destroy(active_sensor->icon);
329
330 g_debug("-- destroying active sensor value...");
331 ctk_widget_destroy(active_sensor->value);
332
333 g_debug("-- destroying active sensor graph and frame...");
334 ctk_widget_destroy(active_sensor->graph);
335 ctk_widget_destroy(active_sensor->graph_frame);
336
337 g_debug("-- destroying active sensor values...");
338 g_free(active_sensor->sensor_values);
339
340 active_sensor_all_alarms_off(active_sensor);
341
342 g_free(active_sensor);
343}
344
345gboolean graph_draw_cb(CtkWidget *graph,
346 cairo_t *cr,
347 gpointer data) {
348
349 ActiveSensor *as;
350
351 as = (ActiveSensor *)data;
352
353 active_sensor_update_graph(as, cr);
1
Calling 'active_sensor_update_graph'
354 /* propagate event onwards */
355
356 return FALSE(0);
357}
358
359static void active_sensor_set_graph_dimensions(ActiveSensor *as,
360 gint width,
361 gint height) {
362
363 gdouble *old_values;
364 gint num_samples, old_num_samples;
365 gint graph_width, graph_height;
366
367 /* dimensions are really for graph frame, so need to remove
368 * extra width added by graph frame - make sure not less than
369 * 1 - always need atleast 1 sample */
370 graph_width = CLAMP(width - GRAPH_FRAME_EXTRA_WIDTH, 1, width - GRAPH_FRAME_EXTRA_WIDTH)(((width - 6) > (width - 6)) ? (width - 6) : (((width - 6)
< (1)) ? (1) : (width - 6)))
;
371 graph_height = CLAMP(height - GRAPH_FRAME_EXTRA_WIDTH, 1 , height - GRAPH_FRAME_EXTRA_WIDTH)(((height - 6) > (height - 6)) ? (height - 6) : (((height -
6) < (1)) ? (1) : (height - 6)))
;
372
373 g_debug("setting graph dimensions to %d x %d", graph_width, graph_height);
374 num_samples = graph_width;
375
376 if (as->sensor_values) {
377 old_values = as->sensor_values;
378 old_num_samples = as->num_samples;
379
380 as->num_samples = num_samples;
381 as->sensor_values = g_new0 (gdouble, as->num_samples)((gdouble *) g_malloc0_n ((as->num_samples), sizeof (gdouble
)))
;
382 memcpy(as->sensor_values,
383 old_values,
384 MIN(old_num_samples, as->num_samples)(((old_num_samples) < (as->num_samples)) ? (old_num_samples
) : (as->num_samples))
*sizeof(gdouble));
385
386 g_free(old_values);
387 } else {
388 as->sensor_values = g_new0 (gdouble, num_samples)((gdouble *) g_malloc0_n ((num_samples), sizeof (gdouble)));
389 as->num_samples = num_samples;
390 }
391
392 /* update graph frame size request */
393 ctk_widget_set_size_request(as->graph,
394 graph_width,
395 graph_height);
396}
397
398void active_sensor_update_graph_dimensions(ActiveSensor *as,
399 gint sizes[2]) {
400
401 active_sensor_set_graph_dimensions(as, sizes[0], sizes[1]);
402 ctk_widget_queue_draw (as->graph);
403}
404
405ActiveSensor *active_sensor_new(SensorsApplet *sensors_applet,
406 CtkTreeRowReference *sensor_row) {
407
408 ActiveSensor *active_sensor;
409 CafePanelAppletOrient orient;
410 gint graph_size;
411 gboolean horizontal;
412
413 g_assert(sensors_applet)do { if (sensors_applet) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 413, ((const char*) (__func__)), "sensors_applet"
); } while (0)
;
414 g_assert(sensor_row)do { if (sensor_row) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 414, ((const char*) (__func__)), "sensor_row"
); } while (0)
;
415
416 g_debug("creating new active sensor");
417
418 active_sensor = g_new0(ActiveSensor, 1)((ActiveSensor *) g_malloc0_n ((1), sizeof (ActiveSensor)));
419 active_sensor->sensors_applet = sensors_applet;
420
421 active_sensor->sensor_row = sensor_row;
422
423#ifdef HAVE_LIBNOTIFY1
424 /* set a base time, creation -5 minutes */
425 active_sensor->ierror_ts = time(NULL((void*)0)) - 300;
426#endif
427
428 int i;
429 for (i = 0; i < NUM_ALARMS2; i++) {
430 active_sensor->alarm_timeout_id[i] = -1;
431 }
432
433 active_sensor->label = ctk_label_new("");
434 active_sensor->value = ctk_label_new("");
435 active_sensor->icon = ctk_image_new();
436
437 active_sensor->graph = ctk_drawing_area_new();
438 active_sensor->graph_frame = ctk_frame_new(NULL((void*)0));
439 ctk_frame_set_shadow_type(CTK_FRAME(active_sensor->graph_frame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->graph_frame)), ((ctk_frame_get_type ()
))))))
,
440 CTK_SHADOW_IN);
441 ctk_container_add(CTK_CONTAINER(active_sensor->graph_frame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->graph_frame)), ((ctk_container_get_type
()))))))
,
442 active_sensor->graph);
443 ctk_widget_add_events(active_sensor->graph_frame,
444 CDK_ALL_EVENTS_MASK);
445
446 /* need to set size according to orientation */
447 orient = cafe_panel_applet_get_orient(active_sensor->sensors_applet->applet);
448 graph_size = g_settings_get_int(active_sensor->sensors_applet->settings, GRAPH_SIZE"graph-size");
449
450 horizontal = ((orient == CAFE_PANEL_APPLET_ORIENT_UP) ||
451 (orient == CAFE_PANEL_APPLET_ORIENT_DOWN));
452
453 active_sensor_set_graph_dimensions(active_sensor,
454 (horizontal ? graph_size : sensors_applet->size),
455 (horizontal ? sensors_applet->size : graph_size));
456
457 g_signal_connect(G_OBJECT(active_sensor->graph),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((active_sensor->graph)), (((GType) ((20
) << (2))))))))), ("draw"), (((GCallback) (graph_draw_cb
))), (active_sensor), ((void*)0), (GConnectFlags) 0)
458 "draw",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((active_sensor->graph)), (((GType) ((20
) << (2))))))))), ("draw"), (((GCallback) (graph_draw_cb
))), (active_sensor), ((void*)0), (GConnectFlags) 0)
459 G_CALLBACK(graph_draw_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((active_sensor->graph)), (((GType) ((20
) << (2))))))))), ("draw"), (((GCallback) (graph_draw_cb
))), (active_sensor), ((void*)0), (GConnectFlags) 0)
460 active_sensor)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((active_sensor->graph)), (((GType) ((20
) << (2))))))))), ("draw"), (((GCallback) (graph_draw_cb
))), (active_sensor), ((void*)0), (GConnectFlags) 0)
;
461
462 active_sensor->updated = FALSE(0);
463 return active_sensor;
464}
465
466static void active_sensor_update_sensor_value(ActiveSensor *as,
467 gdouble sensor_value) {
468
469 /* only if have more than 1 sample stored */
470 if (as->num_samples > 1) {
471 memmove(&(as->sensor_values[1]),
472 as->sensor_values,
473 (as->num_samples - 1)*sizeof(gdouble));
474 }
475
476 as->sensor_values[0] = sensor_value;
477}
478
479void active_sensor_update(ActiveSensor *active_sensor,
480 SensorsApplet *sensors_applet) {
481
482 CtkTreeModel *model;
483 CtkTreeIter iter;
484 CtkTreePath *path;
485
486 /* instance data from the tree for this sensor */
487 gchar *sensor_path = NULL((void*)0);
488 gchar *sensor_id = NULL((void*)0);
489 gchar *sensor_label = NULL((void*)0);
490 SensorType sensor_type;
491 gchar *sensor_interface;
492 gboolean sensor_enabled;
493 gdouble sensor_low_value;
494 gdouble sensor_high_value;
495 gboolean sensor_alarm_enabled;
496 gdouble sensor_multiplier;
497 gdouble sensor_offset;
498 gdouble sensor_value;
499 GdkPixbuf *icon_pixbuf;
500 gchar *graph_color;
501 gint label_min_width;
502 gint label_width;
503 CtkRequisition req;
504
505 /* to build the list of labels as we go */
506 gchar *value_text = NULL((void*)0);
507 gchar *old_value_text;
508
509 TemperatureScale scale;
510 DisplayMode display_mode;
511
512 GError *error = NULL((void*)0);
513
514 gchar *tooltip = NULL((void*)0);
515 gchar *value_tooltip = NULL((void*)0);
516
517 /* hidden gsettings options */
518 gint font_size = 0;
519 gboolean hide_units = FALSE(0);
520 gboolean hide_units_old = FALSE(0);
521
522 g_assert(active_sensor)do { if (active_sensor) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 522, ((const char*) (__func__)), "active_sensor"
); } while (0)
;
523 g_assert(active_sensor->sensor_row)do { if (active_sensor->sensor_row) ; else g_assertion_message_expr
("sensors-applet", "active-sensor.c", 523, ((const char*) (__func__
)), "active_sensor->sensor_row"); } while (0)
;
524 g_assert(sensors_applet)do { if (sensors_applet) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 524, ((const char*) (__func__)), "sensors_applet"
); } while (0)
;
525
526 model = ctk_tree_row_reference_get_model(active_sensor->sensor_row);
527 path = ctk_tree_row_reference_get_path(active_sensor->sensor_row);
528
529 /* if can successfully get iter can proceed */
530 if (ctk_tree_model_get_iter(model, &iter, path)) {
531 ctk_tree_path_free(path);
532 ctk_tree_model_get(CTK_TREE_MODEL(sensors_applet->sensors)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sensors_applet->sensors)), ((ctk_tree_model_get_type (
)))))))
,
533 &iter,
534 PATH_COLUMN, &sensor_path,
535 ID_COLUMN, &sensor_id,
536 LABEL_COLUMN, &sensor_label,
537 INTERFACE_COLUMN, &sensor_interface,
538 SENSOR_TYPE_COLUMN, &sensor_type,
539 ENABLE_COLUMN, &sensor_enabled,
540 LOW_VALUE_COLUMN, &sensor_low_value,
541 HIGH_VALUE_COLUMN, &sensor_high_value,
542 ALARM_ENABLE_COLUMN, &sensor_alarm_enabled,
543 MULTIPLIER_COLUMN, &sensor_multiplier,
544 OFFSET_COLUMN, &sensor_offset,
545 ICON_PIXBUF_COLUMN, &icon_pixbuf,
546 GRAPH_COLOR_COLUMN, &graph_color,
547 -1);
548
549 SensorsAppletPluginGetSensorValue get_sensor_value;
550 /* only call function if is in hash table for plugin */
551 if ((get_sensor_value = sensors_applet_plugins_get_sensor_value_func(sensors_applet, sensor_interface)) != NULL((void*)0)) {
552 sensor_value = get_sensor_value(sensor_path,
553 sensor_id,
554 sensor_type,
555 &error);
556
557 if (error) {
558 g_debug("Error updating active sensor: %s", error->message);
559 sensors_applet_notify_active_sensor(active_sensor,
560 SENSOR_INTERFACE_ERROR);
561
562 /* hard code text as ERROR */
563 value_text = g_strdup(_("ERROR")gettext ("ERROR"));
564 value_tooltip = g_strdup_printf("- %s", error->message);
565 g_error_free(error);
566 error = NULL((void*)0);
567
568 /* set sensor value to an error code -
569 * note this is not unique */
570 sensor_value = -1;
571 } else {
572 /* use hidden gsettings key for hide_units */
573 hide_units_old = hide_units;
574 hide_units = g_settings_get_boolean(sensors_applet->settings, HIDE_UNITS"hide-units");
575
576 /* scale value and set text using this value */
577 switch (sensor_type) {
578 case TEMP_SENSOR:
579 scale = (TemperatureScale) g_settings_get_int(sensors_applet->settings, TEMPERATURE_SCALE"temperature-scale");
580 /* scale value */
581 sensor_value = sensors_applet_convert_temperature(sensor_value, CELSIUS, scale);
582
583 sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
584 switch (scale) {
585 case FAHRENHEIT:
586 value_text = g_strdup_printf("%2.0f %s", sensor_value, (hide_units ? "" : UNITS_FAHRENHEIT"\302\260F"));
587 /* tooltip should
588 * always display
589 * units */
590 value_tooltip = g_strdup_printf("%2.0f %s", sensor_value, UNITS_FAHRENHEIT"\302\260F");
591
592 break;
593 case CELSIUS:
594 value_text = g_strdup_printf("%2.0f %s", sensor_value, (hide_units ? "" : UNITS_CELSIUS"\302\260C"));
595 value_tooltip = g_strdup_printf("%2.0f %s", sensor_value, UNITS_CELSIUS"\302\260C");
596 break;
597 case KELVIN:
598 value_text = g_strdup_printf("%2.0f", sensor_value);
599 value_tooltip = g_strdup(value_text);
600 break;
601 }
602 break;
603
604 case FAN_SENSOR:
605 sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
606 value_text = g_strdup_printf("%4.0f %s", sensor_value, (hide_units ? "" : UNITS_RPMgettext ("RPM")));
607 value_tooltip = g_strdup_printf("%4.0f %s", sensor_value, UNITS_RPMgettext ("RPM"));
608 break;
609
610 case VOLTAGE_SENSOR:
611 sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
612 value_text = g_strdup_printf("%4.2f %s", sensor_value, (hide_units ? "" : UNITS_VOLTAGEgettext ("V")));
613 value_tooltip = g_strdup_printf("%4.2f %s", sensor_value, UNITS_VOLTAGEgettext ("V"));
614 break;
615
616 case CURRENT_SENSOR:
617 sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
618 value_text = g_strdup_printf("%4.2f %s", sensor_value, (hide_units ? "" : UNITS_CURRENTgettext ("A")));
619 value_tooltip = g_strdup_printf("%4.2f %s", sensor_value, UNITS_CURRENTgettext ("A"));
620 break;
621
622 } /* end switch(sensor_type) */
623 } /* end else on error */
624
625 /* setup for tooltips */
626 if (sensors_applet->show_tooltip)
627 tooltip = g_strdup_printf("%s %s", sensor_label, value_tooltip);
628 g_free(value_tooltip);
629
630 /* only do icons and labels / graphs if needed */
631 display_mode = g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
632
633 /* most users wont have a font size set */
634 font_size = g_settings_get_int (sensors_applet->settings, FONT_SIZE"font-size");
635
636 /* do icon if needed */
637 if (display_mode == DISPLAY_ICON ||
638 display_mode == DISPLAY_ICON_WITH_VALUE) {
639
640 /* update icon if icon range has changed if no
641 * update has been done before */
642 if ((sensor_value_range(sensor_value, sensor_low_value, sensor_high_value) != sensor_value_range(active_sensor->sensor_values[0], active_sensor->sensor_low_value, active_sensor->sensor_high_value)) ||
643 !(active_sensor->updated)) {
644
645 active_sensor_update_sensor_value(active_sensor, sensor_value);
646 active_sensor->sensor_low_value = sensor_low_value;
647 active_sensor->sensor_high_value = sensor_high_value;
648 active_sensor_update_icon(active_sensor, icon_pixbuf, sensor_type);
649 }
650
651 if (tooltip) {
652 ctk_widget_set_tooltip_text(active_sensor->icon, tooltip);
653 }
654 }
655
656 active_sensor_update_sensor_value(active_sensor, sensor_value);
657 active_sensor->sensor_low_value = sensor_low_value;
658 active_sensor->sensor_high_value = sensor_high_value;
659
660 /* do graph if needed */
661 if (display_mode == DISPLAY_GRAPH) {
662 /* update graph color in case has changed */
663 cdk_rgba_parse(&(active_sensor->graph_color), graph_color);
664
665 ctk_widget_queue_draw (active_sensor->graph);
666 if (tooltip) {
667 ctk_widget_set_tooltip_text(active_sensor->graph, tooltip);
668 }
669 }
670
671 old_value_text = value_text;
672
673 if (sensor_alarm_enabled) {
674 if (sensor_value >= sensor_high_value || sensor_value <= sensor_low_value) {
675
676 /* make value text red and
677 * activate alarm */
678 if (display_mode == DISPLAY_LABEL_WITH_VALUE ||
679 display_mode == DISPLAY_ICON_WITH_VALUE ||
680 display_mode == DISPLAY_VALUE) {
681
682 value_text = g_markup_printf_escaped("<span foreground=\"#FF0000\">%s</span>", old_value_text);
683 g_free(old_value_text);
684 }
685
686 /* could have both coditions at once */
687 if (sensor_value >= sensor_high_value) {
688 active_sensor_alarm_on(active_sensor, HIGH_ALARM);
689 }
690
691 if (sensor_value <= sensor_low_value) {
692 active_sensor_alarm_on(active_sensor, LOW_ALARM);
693 }
694
695 } else {
696 /* make sure alarms are off */
697 active_sensor_all_alarms_off(active_sensor);
698 }
699 } else {
700 /* else for if alarm enabled */
701 /* make sure all alarms are off */
702 active_sensor_all_alarms_off(active_sensor);
703 }
704
705 /* do value label */
706 if (display_mode == DISPLAY_LABEL_WITH_VALUE ||
707 display_mode == DISPLAY_ICON_WITH_VALUE ||
708 display_mode == DISPLAY_VALUE) {
709
710 if (font_size) {
711 old_value_text = value_text;
712
713 value_text = g_strdup_printf("<span font_desc=\"%d\">%s</span>", font_size, old_value_text);
714 g_free(old_value_text);
715 }
716
717 /*Keep the label as large as previous size unless hide_units has changed */
718 ctk_widget_get_preferred_size (CTK_WIDGET (active_sensor->value)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->value)), ((ctk_widget_get_type ())))))
)
, &req, NULL((void*)0));
719 if (!(hide_units_old == hide_units)) {
720 label_min_width = 0;
721 } else {
722 label_min_width = req.width;
723 }
724
725 ctk_label_set_markup(CTK_LABEL(active_sensor->value)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->value)), ((ctk_label_get_type ()))))))
, value_text);
726
727 ctk_widget_get_preferred_size (CTK_WIDGET (active_sensor->value)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->value)), ((ctk_widget_get_type ())))))
)
, &req, NULL((void*)0));
728 label_width = MAX(req.width, label_min_width)(((req.width) > (label_min_width)) ? (req.width) : (label_min_width
))
;
729 ctk_widget_set_size_request (CTK_WIDGET (active_sensor->value)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->value)), ((ctk_widget_get_type ())))))
)
, label_min_width, req.height);
730
731 if (tooltip) {
732 ctk_widget_set_tooltip_text(active_sensor->value, tooltip);
733 }
734 }
735 /* finished with value text */
736 g_free(value_text);
737
738 /* do label label */
739 if (display_mode == DISPLAY_LABEL_WITH_VALUE) {
740 if (font_size) {
741 old_value_text = sensor_label;
742 sensor_label = g_strdup_printf("<span font_desc=\"%d\">%s</span>", font_size, old_value_text);
743 g_free(old_value_text);
744 }
745
746 ctk_label_set_markup(CTK_LABEL(active_sensor->label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((active_sensor->label)), ((ctk_label_get_type ()))))))
, sensor_label);
747 if (tooltip) {
748 ctk_widget_set_tooltip_text(active_sensor->label, tooltip);
749 }
750 }
751
752 g_free(tooltip);
753 } else {
754 g_debug("no get_sensor_value function yet installed for interface %s.", sensor_interface);
755 }
756
757 g_free(sensor_path);
758 g_free(sensor_id);
759 g_free(sensor_label);
760 g_free(sensor_interface);
761 g_free(graph_color);
762 g_object_unref(icon_pixbuf);
763
764 } else {
765 g_debug("Error getting iter when updating sensor...");
766 }
767
768 active_sensor->updated = TRUE(!(0));
769
770}
771
772/* to be called when the icon within the CtkRowReference that this
773 * sensor references is changed - updates icon based upon value in the
774 * ActiveSensor */
775void active_sensor_icon_changed(ActiveSensor *active_sensor, SensorsApplet *sensors_applet) {
776
777 CtkTreeModel *model;
778 CtkTreePath *path;
779 CtkTreeIter iter;
780
781 SensorType sensor_type;
782 GdkPixbuf *icon_pixbuf;
783
784 g_assert(active_sensor)do { if (active_sensor) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 784, ((const char*) (__func__)), "active_sensor"
); } while (0)
;
785 g_assert(sensors_applet)do { if (sensors_applet) ; else g_assertion_message_expr ("sensors-applet"
, "active-sensor.c", 785, ((const char*) (__func__)), "sensors_applet"
); } while (0)
;
786
787 model = ctk_tree_row_reference_get_model(active_sensor->sensor_row);
788 path = ctk_tree_row_reference_get_path(active_sensor->sensor_row);
789
790 /* if can successfully get iter can proceed */
791 if (ctk_tree_model_get_iter(model, &iter, path)) {
792 ctk_tree_model_get(CTK_TREE_MODEL(sensors_applet->sensors)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sensors_applet->sensors)), ((ctk_tree_model_get_type (
)))))))
,
793 &iter,
794 SENSOR_TYPE_COLUMN, &sensor_type,
795 ICON_PIXBUF_COLUMN, &icon_pixbuf,
796 -1);
797
798 active_sensor_update_icon(active_sensor, icon_pixbuf, sensor_type);
799 g_object_unref(icon_pixbuf);
800 }
801 ctk_tree_path_free(path);
802}