File: | sensors-applet/active-sensor.c |
Warning: | line 305, column 15 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
36 | typedef 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 | ||||
49 | static const gchar * const temp_overlay_icons[] = { | |||
50 | PIXMAPS_DIR"/usr/share/pixmaps/cafe-sensors-applet/" "very-low-temp-icon.png", | |||
51 | PIXMAPS_DIR"/usr/share/pixmaps/cafe-sensors-applet/" "low-temp-icon.png", | |||
52 | PIXMAPS_DIR"/usr/share/pixmaps/cafe-sensors-applet/" "normal-temp-icon.png", | |||
53 | PIXMAPS_DIR"/usr/share/pixmaps/cafe-sensors-applet/" "high-temp-icon.png", | |||
54 | PIXMAPS_DIR"/usr/share/pixmaps/cafe-sensors-applet/" "very-high-temp-icon.png" | |||
55 | }; | |||
56 | ||||
57 | ||||
58 | static 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 | ||||
65 | static 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 | ||||
78 | static 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 | ||||
98 | static gboolean active_sensor_execute_low_alarm(ActiveSensor *active_sensor) { | |||
99 | return active_sensor_execute_alarm(active_sensor, LOW_ALARM); | |||
100 | } | |||
101 | ||||
102 | static 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 */ | |||
107 | void 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 | ||||
124 | static 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 | ||||
135 | static 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 | */ | |||
192 | gint 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 | ||||
210 | static 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 | ||||
258 | static 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; | |||
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++) { | |||
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); | |||
| ||||
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 | ||||
323 | void 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 | ||||
345 | gboolean 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); | |||
| ||||
354 | /* propagate event onwards */ | |||
355 | ||||
356 | return FALSE(0); | |||
357 | } | |||
358 | ||||
359 | static 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 | ||||
398 | void 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 | ||||
405 | ActiveSensor *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 | ||||
466 | static 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 | ||||
479 | void 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"))g_strdup_inline (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)g_strdup_inline (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 */ | |||
775 | void 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 | } |