2 Copyright (C) 2010-2011 wpitchoune@gmail.com
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.
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.
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 Street, Fifth Floor, Boston, MA
22 #define _(str) gettext(str)
32 #include <sensors/sensors.h>
33 #include <sensors/error.h>
42 #include "ui_sensorlist.h"
51 #ifdef HAVE_REMOTE_SUPPORT
55 #ifdef HAVE_APPINDICATOR
56 #include "ui_appindicator.h"
60 #include "ui_notify.h"
65 static const char *program_name;
69 printf("psensor %s\n", VERSION);
70 printf(_("Copyright (C) %s wpitchoune@gmail.com\n\
71 License GPLv2: GNU GPL version 2 or later \
72 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n\
73 This is free software: you are free to change and redistribute it.\n\
74 There is NO WARRANTY, to the extent permitted by law.\n"),
80 printf(_("Usage: %s [OPTION]...\n"), program_name);
82 puts(_("psensor is a GTK application for monitoring hardware sensors, "
83 "including temperatures and fan speeds."));
88 -h, --help display this help and exit\n\
89 -v, --version display version information and exit"));
95 the URL of the psensor-server, example: http://hostname:3131"));
99 printf(_("Report bugs to: %s\n"), PACKAGE_BUGREPORT);
101 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
105 cb_preferences(gpointer data, guint callback_action, GtkWidget *item)
107 ui_pref_dialog_run((struct ui_psensor *)data);
110 static GtkItemFactoryEntry menu_items[] = {
112 NULL, cb_preferences, 0, "<Item>"},
115 NULL, NULL, 0, "<Separator>"},
118 "", ui_psensor_exit, 0, "<StockItem>", GTK_STOCK_QUIT},
121 static gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
124 Updates the size of the sensor values if different than the
128 update_psensor_values_size(struct psensor **sensors, struct config *cfg)
130 struct psensor **cur;
134 struct psensor *s = *cur;
136 if (s->values_max_length != cfg->sensor_values_max_length)
137 psensor_values_resize(s,
138 cfg->sensor_values_max_length);
144 void update_psensor_measures(struct ui_psensor *ui)
146 struct psensor **sensors = ui->sensors;
147 struct config *cfg = ui->config;
155 update_psensor_values_size(sensors, ui->config);
157 psensor_list_update_measures(sensors);
158 #ifdef HAVE_REMOTE_SUPPORT
159 remote_psensor_list_update(sensors);
162 nvidia_psensor_list_update(sensors);
167 sleep(cfg->sensor_update_interval);
171 gboolean ui_refresh_thread(gpointer data)
175 struct ui_psensor *ui = (struct ui_psensor *)data;
182 graph_update(ui->sensors, ui->w_graph, ui->config);
184 ui_sensorlist_update(ui->ui_sensorlist);
186 #ifdef HAVE_APPINDICATOR
187 ui_appindicator_update(ui);
190 if (ui->graph_update_interval != cfg->graph_update_interval) {
191 ui->graph_update_interval = cfg->graph_update_interval;
198 g_timeout_add(1000 * ui->graph_update_interval,
199 ui_refresh_thread, ui);
205 on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
207 struct ui_psensor *ui_psensor = (struct ui_psensor *)data;
209 graph_update(ui_psensor->sensors,
210 ui_psensor->w_graph, ui_psensor->config);
215 void cb_alarm_raised(struct psensor *sensor, void *data)
217 #ifdef HAVE_LIBNOTIFY
219 ui_notify(sensor, (struct ui_psensor *)data);
223 void associate_colors(struct psensor **sensors)
225 /* number of uniq colors */
226 #define COLORS_COUNT 8
228 unsigned int colors[COLORS_COUNT][3] = {
229 {0x0000, 0x0000, 0x0000}, /* black */
230 {0xffff, 0x0000, 0x0000}, /* red */
231 {0x0000, 0.0000, 0xffff}, /* blue */
232 {0x0000, 0xffff, 0x0000}, /* green */
234 {0x7fff, 0x7fff, 0x7fff}, /* grey */
235 {0x7fff, 0x0000, 0x0000}, /* dark red */
236 {0x0000, 0x0000, 0x7fff}, /* dark blue */
237 {0x0000, 0x7fff, 0x0000} /* dark green */
240 struct psensor **sensor_cur = sensors;
242 while (*sensor_cur) {
243 struct color default_color;
244 color_set(&default_color,
245 colors[i % COLORS_COUNT][0],
246 colors[i % COLORS_COUNT][1],
247 colors[i % COLORS_COUNT][2]);
250 = config_get_sensor_color((*sensor_cur)->id,
258 void associate_cb_alarm_raised(struct psensor **sensors, struct ui_psensor *ui)
260 struct psensor **sensor_cur = sensors;
261 while (*sensor_cur) {
262 struct psensor *s = *sensor_cur;
264 s->cb_alarm_raised = cb_alarm_raised;
265 s->cb_alarm_raised_data = ui;
267 if (is_temp_type(s->type)) {
269 = config_get_sensor_alarm_limit(s->id, 60);
271 = config_get_sensor_alarm_enabled(s->id);
274 s->alarm_enabled = 0;
281 void associate_preferences(struct psensor **sensors)
283 struct psensor **sensor_cur = sensors;
284 while (*sensor_cur) {
286 struct psensor *s = *sensor_cur;
288 s->enabled = config_is_sensor_enabled(s->id);
290 n = config_get_sensor_name(s->id);
299 GtkWidget *ui_get_popupmenu(gpointer data)
301 GtkItemFactory *item_factory;
304 item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
305 gtk_item_factory_create_items(item_factory,
306 nmenu_items, menu_items, data);
307 menu = gtk_item_factory_get_widget(item_factory, "<main>");
312 int on_graph_clicked(GtkWidget *widget, GdkEventButton *event, gpointer data)
316 if (event->type != GDK_BUTTON_PRESS)
319 menu = ui_get_popupmenu(data);
321 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
322 event->button, event->time);
328 GtkWidget *create_graph_widget(struct ui_psensor * ui)
332 w_graph = gtk_drawing_area_new();
334 g_signal_connect(G_OBJECT(w_graph),
335 "expose-event", G_CALLBACK(on_expose_event), ui);
337 gtk_widget_add_events(w_graph, GDK_BUTTON_PRESS_MASK);
338 gtk_signal_connect(GTK_OBJECT(w_graph),
339 "button_press_event",
340 (GCallback) on_graph_clicked, ui);
345 void ui_main_box_create(struct ui_psensor *ui)
348 GtkWidget *w_sensorlist;
353 ui_sensorlist_create_widget(ui->ui_sensorlist);
355 gtk_container_remove(GTK_CONTAINER(ui->main_window),
358 ui->w_graph = create_graph_widget(ui);
359 ui->w_sensorlist = ui->ui_sensorlist->widget;
362 if (cfg->sensorlist_position == SENSORLIST_POSITION_RIGHT
363 || cfg->sensorlist_position == SENSORLIST_POSITION_LEFT)
364 ui->main_box = gtk_hpaned_new();
366 ui->main_box = gtk_vpaned_new();
368 w_sensorlist = gtk_scrolled_window_new(NULL, NULL);
369 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w_sensorlist),
370 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
371 gtk_container_add(GTK_CONTAINER(w_sensorlist),
372 ui->ui_sensorlist->widget);
374 gtk_container_add(GTK_CONTAINER(ui->main_window), ui->main_box);
376 if (cfg->sensorlist_position == SENSORLIST_POSITION_RIGHT
377 || cfg->sensorlist_position == SENSORLIST_POSITION_BOTTOM) {
378 gtk_paned_pack1(GTK_PANED(ui->main_box),
379 GTK_WIDGET(ui->w_graph), TRUE, TRUE);
380 gtk_paned_pack2(GTK_PANED(ui->main_box),
381 w_sensorlist, FALSE, TRUE);
383 gtk_paned_pack1(GTK_PANED(ui->main_box),
384 w_sensorlist, FALSE, TRUE);
385 gtk_paned_pack2(GTK_PANED(ui->main_box),
386 GTK_WIDGET(ui->w_graph), TRUE, TRUE);
389 gtk_widget_show_all(ui->main_box);
392 static struct option long_options[] = {
393 {"version", no_argument, 0, 'v'},
394 {"help", no_argument, 0, 'h'},
395 {"url", required_argument, 0, 'u'},
399 int main(int argc, char **argv)
401 struct ui_psensor ui;
408 program_name = argv[0];
410 setlocale(LC_ALL, "");
413 bindtextdomain(PACKAGE, LOCALEDIR);
417 while ((optc = getopt_long(argc, argv, "vhu:", long_options,
422 url = strdup(optarg);
436 if (!cmdok || optind != argc) {
437 fprintf(stderr, _("Try `%s --help' for more information.\n"),
446 gtk_init(&argc, &argv);
448 #ifdef HAVE_LIBNOTIFY
449 ui.notification_last_time = NULL;
454 ui.config = config_load();
456 err = lmsensor_init();
458 fprintf(stderr, _("ERROR: lmsensor init failure: %s\n"),
459 sensors_strerror(err));
464 #ifdef HAVE_REMOTE_SUPPORT
466 ui.sensors = get_remote_sensors(url, 600);
469 _("ERROR: Not compiled with remote sensor support.\n"));
474 struct psensor **tmp;
476 tmp = get_all_sensors(600);
477 ui.sensors = nvidia_psensor_list_add(tmp, 600);
479 if (tmp != ui.sensors)
482 ui.sensors = get_all_sensors(600);
486 associate_preferences(ui.sensors);
487 associate_colors(ui.sensors);
488 associate_cb_alarm_raised(ui.sensors, &ui);
491 ui.main_window = ui_window_create(&ui);
495 ui.w_graph = create_graph_widget(&ui);
498 ui.ui_sensorlist = ui_sensorlist_create(ui.sensors);
500 ui_main_box_create(&ui);
502 gtk_widget_show_all(ui.main_window);
504 thread = g_thread_create((GThreadFunc) update_psensor_measures,
510 ui.graph_update_interval = ui.config->graph_update_interval;
512 g_timeout_add(1000 * ui.graph_update_interval, ui_refresh_thread, &ui);
514 #ifdef HAVE_APPINDICATOR
515 ui_appindicator_init(&ui);
523 psensor_list_free(ui.sensors);