1 /* GKrellM
2 | Copyright (C) 1999-2019 Bill Wilson
3 |
4 | Author: Bill Wilson billw@gkrellm.net
5 | Latest versions might be found at: http://gkrellm.net
6 |
7 |
8 | GKrellM is free software: you can redistribute it and/or modify it
9 | under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | GKrellM is distributed in the hope that it will be useful, but WITHOUT
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 | License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program. If not, see http://www.gnu.org/licenses/
20 |
21 |
22 | Additional permission under GNU GPL version 3 section 7
23 |
24 | If you modify this program, or any covered work, by linking or
25 | combining it with the OpenSSL project's OpenSSL library (or a
26 | modified version of that library), containing parts covered by
27 | the terms of the OpenSSL or SSLeay licenses, you are granted
28 | additional permission to convey the resulting work.
29 | Corresponding Source for a non-source form of such a combination
30 | shall include the source code for the parts of OpenSSL used as well
31 | as that of the covered work.
32 */
33
34 #include "gkrellm.h"
35 #include "gkrellm-sysdeps.h"
36 #include "gkrellm-private.h"
37
38 #define PPP_LOCK_FILE "LCK..modem"
39
40 #define TIMER_TYPE_NONE 0
41 #define TIMER_TYPE_PPP 1
42 #define TIMER_TYPE_IPPP 2
43 #define TIMER_TYPE_SERVER 3
44
45
46 #define N_DAY_STATS 31
47 #define N_WEEK_STATS 26
48 #define N_MONTH_STATS 12
49
50 typedef struct
51 {
52 gchar *date;
53 gdouble rx,
54 tx;
55 gint connect_time;
56 }
57 NetStat;
58
59 enum StatType
60 {
61 DAY_STAT,
62 WEEK_STAT,
63 MONTH_STAT
64 };
65
66
67 typedef struct
68 {
69 gchar *name;
70 GtkWidget *vbox,
71 *parent_vbox;
72 GtkWidget *enable_button,
73 *force_button,
74 *alert_button,
75 *label_entry;
76 GkrellmChart *chart;
77 GkrellmChartdata *rx_cd,
78 *tx_cd;
79 GkrellmDecal *rxled,
80 *txled;
81
82 /* All known net interfaces are in the net_mon_list. Only interfaces
83 | which are up or forced up and are config enabled will actually have
84 | a chart created, unless the interface is linked to the timer button.
85 | A linked interface always has a chart created for it regardless
86 | of the up state but it will have a chart that may not be
87 | visible if the interface is down (ppp) or the connect state is
88 | hangup (ippp).
89 */
90 gboolean locked; /* True if linked to timer button or forced up */
91
92 GkrellmChartconfig *chart_config;
93 gboolean enabled,
94 ignore,
95 chart_labels,
96 force_up,
97 real;
98
99 gchar *label;
100
101 GkrellmAlert *alert;
102 GtkWidget *alert_config_rx_button,
103 *alert_config_tx_button;
104 gboolean alert_uses_rx,
105 alert_uses_tx;
106
107 gulong rx_old,
108 tx_old;
109 gint rx_current,
110 tx_current;
111 gdouble rx_totalA,
112 rx_totalB,
113 tx_totalA,
114 tx_totalB;
115
116 NetStat day_stats[N_DAY_STATS],
117 week_stats[N_WEEK_STATS],
118 month_stats[N_MONTH_STATS];
119
120 gboolean show_totalB,
121 totals_shown,
122 reset_button_in,
123 stats_button_in,
124 mouse_in_chart,
125 new_text_format;
126 GkrellmLauncher launch;
127 GtkWidget *launch_entry,
128 *tooltip_entry;
129
130 gboolean up,
131 up_prev,
132 up_event,
133 down_event;
134
135 gulong rx,
136 tx;
137 }
138 NetMon;
139
140
141 static void cb_alert_config(GkrellmAlert *ap, NetMon *net);
142 static void cb_alert_config_create(GkrellmAlert *ap, GtkWidget *vbox,
143 NetMon *net);
144 static void net_stat_init(NetMon *net);
145
146 typedef struct
147 {
148 gchar *name;
149 gint type;
150 }
151 TimerType;
152
153
154 static GList *net_mon_list;
155 static GList *net_mon_sys_list;
156 static GList *timer_defaults_list;
157 static gchar *lock_directory;
158 static gchar *net_data_dir;
159 static gchar *net_ignore_patterns;
160
161 static void (*read_net_data)();
162 static void (*check_net_routes)();
163 static gboolean (*isdn_is_online)();
164
165 static gboolean net_use_routed;
166 static gboolean net_config_use_routed;
167
168 static gint reset_mday;
169
170 static gboolean net_enabled_as_default;
171 static GtkWidget *net_enabled_as_default_button;
172
173
174 static gint
strcmp_net_name(NetMon * net1,NetMon * net2)175 strcmp_net_name(NetMon *net1, NetMon *net2)
176 {
177 gchar *s;
178 gint n, n1, n2, len;
179
180 for (s = net1->name; *s; ++s)
181 if (isdigit((unsigned char)*s))
182 break;
183 if (!*s)
184 return strcmp(net1->name, net2->name);
185 n1 = atoi(s);
186 len = s - net1->name;
187 n = strncmp(net1->name, net2->name, len);
188 if (n == 0)
189 {
190 n2 = atoi(net2->name + len);
191 if (n1 < n2)
192 n = -1;
193 else if (n1 > n2)
194 n = 1;
195 }
196 return n;
197 }
198
199 static gboolean
net_ignore_match(gchar * name)200 net_ignore_match(gchar *name)
201 {
202 GMatchInfo *match_info;
203 GRegex *regex;
204 gchar *s, buf[128];
205
206 for (s = net_ignore_patterns; *s; )
207 {
208 while (*s == ' ')
209 ++s;
210 if (sscanf(s, "%s", buf) == 1)
211 {
212 regex = g_regex_new(buf, G_REGEX_ANCHORED, 0, NULL);
213 if (regex)
214 {
215 g_regex_match(regex, name, 0, &match_info);
216 if (g_match_info_matches(match_info))
217 {
218 g_match_info_free(match_info);
219 g_regex_unref(regex);
220 return TRUE;
221 }
222 g_match_info_free(match_info);
223 g_regex_unref(regex);
224 }
225 }
226 while (*s != ' ' && *s != '\0')
227 ++s;
228 }
229 return FALSE;
230 }
231
232 static NetMon *
new_net(gchar * name)233 new_net(gchar *name)
234 {
235 NetMon *net;
236
237 net = g_new0(NetMon, 1);
238 net->name = g_strdup(name);
239 if (strcmp(name, "lo")) /* lo is disabled by default */
240 net->enabled = net_enabled_as_default; /* All others are enabled unless unset in configuration */
241 if (net_ignore_match(name))
242 {
243 net->ignore = TRUE;
244 net->enabled = FALSE;
245 }
246 net->chart_labels = TRUE;
247 net->label = g_strdup("");
248 net->launch.command = g_strdup("");
249 net->launch.tooltip_comment = g_strdup("");
250 net->alert_uses_rx = net->alert_uses_tx = TRUE;
251 net_mon_list = g_list_insert_sorted(net_mon_list, net,
252 (GCompareFunc) strcmp_net_name);
253
254 net_stat_init(net);
255
256 return net;
257 }
258
259 static NetMon *
lookup_net(gchar * name)260 lookup_net(gchar *name)
261 {
262 NetMon *net;
263 GList *list;
264
265 if (!name)
266 return NULL;
267 for (list = net_mon_list; list; list = list->next)
268 {
269 net = (NetMon *) list->data;
270 if (!strcmp(net->name, name))
271 return net;
272 }
273 return NULL;
274 }
275
276 /* ------------- Net monitor to system dependent interface ------------- */
277
278 void
gkrellm_net_client_divert(void (* read_func)(),void (* check_routes)(),gboolean (* isdn_online_func)())279 gkrellm_net_client_divert(void (*read_func)(), void (*check_routes)(),
280 gboolean (*isdn_online_func)())
281 {
282 read_net_data = read_func;
283 check_net_routes = check_routes;
284 isdn_is_online = isdn_online_func;
285 }
286
287 static gboolean
setup_net_interface(void)288 setup_net_interface(void)
289 {
290 if (!read_net_data && !_GK.client_mode && gkrellm_sys_net_init())
291 {
292 read_net_data = gkrellm_sys_net_read_data;
293 check_net_routes = gkrellm_sys_net_check_routes;
294 isdn_is_online = gkrellm_sys_net_isdn_online;
295 }
296 return read_net_data ? TRUE : FALSE;
297 }
298
299 gchar *
gkrellm_net_mon_first(void)300 gkrellm_net_mon_first(void)
301 {
302 gchar *name = NULL;
303
304 net_mon_sys_list = net_mon_list;
305 if (net_mon_sys_list)
306 {
307 name = ((NetMon *) (net_mon_sys_list->data))->name;
308 net_mon_sys_list = net_mon_sys_list->next;
309 }
310 return name;
311 }
312
313 gchar
gkrellm_net_mon_next(void)314 *gkrellm_net_mon_next(void)
315 {
316 gchar *name = NULL;
317
318 if (net_mon_sys_list)
319 {
320 name = ((NetMon *) (net_mon_sys_list->data))->name;
321 net_mon_sys_list = net_mon_sys_list->next;
322 }
323 return name;
324 }
325
326 void
gkrellm_net_use_routed(gboolean real_routed)327 gkrellm_net_use_routed(gboolean real_routed)
328 {
329 /* real_routed should only ever be FALSE when called from client.c to
330 | handle the server sysdep net code not using routed mode while the
331 | client <-> server interface will always use routed mode.
332 */
333 net_use_routed = TRUE;
334 net_config_use_routed = real_routed;
335 }
336
337 void
gkrellm_net_routed_event(gchar * name,gboolean routed)338 gkrellm_net_routed_event(gchar *name, gboolean routed)
339 {
340 NetMon *net;
341
342 if (!net_use_routed)
343 return;
344 if ((net = lookup_net(name)) == NULL)
345 net = new_net(name);
346 if (!net)
347 return;
348
349 if (routed)
350 net->up_event = TRUE;
351 else
352 net->down_event = TRUE;
353 net->up = routed;
354 net->real = TRUE;
355 }
356
357 void
gkrellm_net_assign_data(gchar * name,gulong rx,gulong tx)358 gkrellm_net_assign_data(gchar *name, gulong rx, gulong tx)
359 {
360 NetMon *net;
361
362 if ((net = lookup_net(name)) == NULL)
363 net = new_net(name);
364 if (!net || net->ignore)
365 return;
366
367 if (GK.second_tick && !net_use_routed)
368 net->up = TRUE;
369 net->rx = rx;
370 net->tx = tx;
371 net->real = TRUE;
372 }
373
374 void
gkrellm_net_add_timer_type_ppp(gchar * name)375 gkrellm_net_add_timer_type_ppp(gchar *name)
376 {
377 TimerType *t;
378
379 if (!name || !*name || _GK.client_mode)
380 return;
381 t = g_new0(TimerType, 1);
382 t->name = g_strdup(name);
383 t->type = TIMER_TYPE_PPP;
384 timer_defaults_list = g_list_append(timer_defaults_list, t);
385 }
386
387 void
gkrellm_net_add_timer_type_ippp(gchar * name)388 gkrellm_net_add_timer_type_ippp(gchar *name)
389 {
390 TimerType *t;
391
392 if (!name || !*name || _GK.client_mode)
393 return;
394 t = g_new0(TimerType, 1);
395 t->name = g_strdup(name);
396 t->type = TIMER_TYPE_IPPP;
397 timer_defaults_list = g_list_append(timer_defaults_list, t);
398 }
399
400 void
gkrellm_net_set_lock_directory(gchar * dir)401 gkrellm_net_set_lock_directory(gchar *dir)
402 {
403 lock_directory = g_strdup(dir);
404 }
405
406
407 /* ======================================================================== */
408 /* Exporting net data for plugins */
409
410 gint
gkrellm_net_routes(void)411 gkrellm_net_routes(void)
412 {
413 return g_list_length(net_mon_list);
414 }
415
416 gboolean
gkrellm_net_stats(gint n,gchar * name,gulong * rx,gulong * tx)417 gkrellm_net_stats(gint n, gchar *name, gulong *rx, gulong *tx)
418 {
419 GList *list;
420 NetMon *net;
421
422 list = g_list_nth(net_mon_list, n);
423 if (!list)
424 return FALSE;
425 net = (NetMon *) list->data;
426 if (name)
427 strcpy(name, net->name);
428 if (rx)
429 *rx = net->rx;
430 if (tx)
431 *tx = net->tx;
432 return TRUE;
433 }
434
435 void
gkrellm_net_led_positions(gint * x_rx_led,gint * y_rx_led,gint * x_tx_led,gint * y_tx_led)436 gkrellm_net_led_positions(gint *x_rx_led, gint *y_rx_led,
437 gint *x_tx_led, gint *y_tx_led)
438 {
439 if (x_rx_led)
440 *x_rx_led = _GK.rx_led_x;
441 if (y_rx_led)
442 *y_rx_led = _GK.rx_led_y;
443 if (x_tx_led)
444 *x_tx_led = _GK.tx_led_x;
445 if (y_tx_led)
446 *y_tx_led = _GK.tx_led_y;
447 }
448
449 /* ======================================================================== */
450 #include "pixmaps/net/decal_net_leds.xpm"
451 #include "pixmaps/timer/bg_timer.xpm"
452 #include "pixmaps/timer/decal_timer_button.xpm"
453
454 /* ISO 8601 date and month format strings for network stats gui*/
455 #ifdef WIN32
456 #define GK_NET_ISO_DATE "%Y-%m-%d"
457 #define GK_NET_MONTH_STAT_DATE "%b %d"
458 #else
459 #define GK_NET_ISO_DATE "%F"
460 #define GK_NET_MONTH_STAT_DATE "%b %e"
461 #endif
462
463 #define MIN_GRID_RES 5
464 #define MAX_GRID_RES 500000000
465 #define DEFAULT_GRID_RES 20000
466
467 /* States for the timer button are indexes to the corresponding
468 | timer button decal frame shown.
469 */
470 #define TB_NORMAL 0
471 #define TB_PRESSED 1
472 #define TB_STANDBY 2
473 #define TB_ON 3
474 #define N_TB_DECALS 4
475
476 #define RX_LED 0
477 #define TX_LED 1
478
479 #define RX_OFF 0
480 #define RX_ON 1
481 #define TX_OFF 2
482 #define TX_ON 3
483 #define N_LEDS 4
484
485 static GkrellmMonitor *mon_net;
486 static GkrellmMonitor *mon_timer;
487
488
489 static NetMon *net_timed; /* Monitor linked to timer button */
490
491 GkrellmPanel *timer_panel; /* For the timer and button */
492
493 static GtkWidget *net_vbox; /* Where all net monitors live */
494 static GtkWidget *dynamic_net_vbox;
495 static GtkWidget *timer_vbox;
496
497 static GkrellmPiximage *bg_timer_piximage,
498 *decal_net_led_piximage,
499 *decal_timer_button_piximage;
500
501 static GkrellmStyle *bg_timer_style;
502
503 static GdkPixmap *decal_net_led_pixmap;
504 static GdkBitmap *decal_net_led_mask;
505
506 static GdkPixmap *decal_timer_button_pixmap;
507 static GdkBitmap *decal_timer_button_mask;
508
509 static GkrellmDecal *time_decal,
510 *seconds_decal,
511 *button_decal;
512
513 /* These 3 decals will be drawn on net charts when mouse is in a chart and
514 | the chart has a rx and/or tx total drawn. They won't live in a panel
515 | so must be managed differently from decals on a panel.
516 */
517 static GkrellmDecal *decal_totalA,
518 *decal_totalB,
519 *decal_reset;
520 static GkrellmDecal *decal_stats;
521
522 static gchar *timer_on_command;
523 static gchar *timer_off_command;
524 static gchar *timer_button_iface;
525 static gint timer_button_enabled;
526 static gint last_time = -1;
527
528
529 static gint timer_button_type = TIMER_TYPE_NONE,
530 timer_button_state,
531 timer_button_old_state,
532 last_timer_command;
533
534 static gboolean timer_seconds;
535
536 static gint check_connect_state,
537 net_stats_window_height;
538
539 static gint ascent,
540 ascent_alt,
541 sec_pad;
542
543 static time_t net_timer0;
544
545 static gint net_style_id,
546 timer_style_id;
547
548 static GkrellmSizeAbbrev stats_bytes_abbrev[] =
549 {
550 { KB_SIZE(1), 1, "%.0f" },
551 { KB_SIZE(10), KB_SIZE(1), "%.1fKB" },
552 { MB_SIZE(1), KB_SIZE(1), "%.2fKB" },
553 { MB_SIZE(10), MB_SIZE(1), "%.3fMB" },
554 { MB_SIZE(100), MB_SIZE(1), "%.2fMB" },
555 { GB_SIZE(1), MB_SIZE(1), "%.2fMB" },
556 { GB_SIZE(10), GB_SIZE(1), "%.3fGB" },
557 { GB_SIZE(100), GB_SIZE(1), "%.2fGB" },
558 { TB_SIZE(1), GB_SIZE(1), "%.2fGB" },
559 { TB_SIZE(10), TB_SIZE(1), "%.3fTB" },
560 { TB_SIZE(100), TB_SIZE(1), "%.3fTB" },
561 { TB_SIZE(1000), TB_SIZE(1), "%.2fTB" }
562 };
563
564 #define NET_DATA_VERSION 2
565
566 #define SATURDAY 6
567 #define SUNDAY 0
568
569 static gchar days_in_month[12] =
570 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
571
572
573 /* Called from client.c
574 */
575 void
gkrellm_net_server_has_timer(void)576 gkrellm_net_server_has_timer(void)
577 {
578 timer_button_type = TIMER_TYPE_SERVER;
579 }
580
581 static void
draw_led(NetMon * net,int rxtx,int led_index)582 draw_led(NetMon *net, int rxtx, int led_index)
583 {
584 GkrellmPanel *p;
585 GkrellmDecal *led;
586
587 if (!net->chart)
588 return;
589 p = net->chart->panel;
590 if (rxtx == RX_LED)
591 led = net->rxled;
592 else
593 led = net->txled;
594
595 gkrellm_draw_decal_pixmap(p, led, led_index);
596 }
597
598 static void
draw_timer(GkrellmPanel * p,gint seconds,gint force)599 draw_timer(GkrellmPanel *p, gint seconds, gint force)
600 {
601 static gint prev_minute = -1,
602 prev_hour = -1;
603 gint minutes, hours, w;
604 gchar buf[32], buf_sec[16];
605
606 last_time = seconds;
607 hours = seconds / 60 / 60;
608 minutes = (seconds / 60) % 60;
609 seconds = seconds % 60;
610 snprintf(buf, sizeof(buf), "%2d:%02d", hours, minutes);
611 snprintf(buf_sec, sizeof(buf_sec), "%02d", seconds);
612
613 if (prev_minute != minutes || prev_hour != hours || force)
614 {
615 w = gkrellm_gdk_string_width(time_decal->text_style.font, buf);
616 if (timer_seconds && w + seconds_decal->w + sec_pad <= time_decal->w)
617 {
618 time_decal->x_off = time_decal->w - w - seconds_decal->w - sec_pad
619 - time_decal->text_style.effect;
620 gkrellm_make_decal_visible(p, seconds_decal);
621 }
622 else
623 {
624 time_decal->x_off = time_decal->w - w
625 - time_decal->text_style.effect;
626 if (time_decal->x_off < 0)
627 time_decal->x_off = 0;
628 gkrellm_make_decal_invisible(p, seconds_decal);
629 }
630 }
631 prev_minute = minutes;
632 prev_hour = hours;
633
634 gkrellm_draw_decal_text(p, time_decal, buf,
635 force ? -1 : (hours * 60 + minutes));
636
637 if (gkrellm_is_decal_visible(seconds_decal))
638 gkrellm_draw_decal_text(p, seconds_decal, buf_sec,
639 force ? -1 : seconds);
640
641 gkrellm_draw_panel_layers(timer_panel);
642 }
643
644 /* --------- net stats window -----------
645 */
646 enum
647 {
648 DATE_COLUMN,
649 RX_COLUMN,
650 TX_COLUMN,
651 TOTAL_COLUMN,
652 TIME_COLUMN,
653 N_STATS_COLUMNS
654 };
655
656 static GtkTreeModel *
stats_model_create(NetMon * net,NetStat * ns,gint n_stats)657 stats_model_create(NetMon *net, NetStat *ns, gint n_stats)
658 {
659 GtkListStore *store;
660 GtkTreeIter iter;
661 gchar rx[64], tx[64], total[64], time[64];
662 gint i, hours, minutes;
663
664 store = gtk_list_store_new(N_STATS_COLUMNS,
665 G_TYPE_STRING,
666 G_TYPE_STRING,
667 G_TYPE_STRING,
668 G_TYPE_STRING,
669 G_TYPE_STRING);
670
671 for (i = 0; i < n_stats; ++i, ++ns)
672 {
673 if (i > 0 && !strncmp(ns->date, "---", 3))
674 continue;
675 gkrellm_format_size_abbrev(rx, sizeof(rx), (gfloat) ns->rx,
676 &stats_bytes_abbrev[0],
677 sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
678 gkrellm_format_size_abbrev(tx, sizeof(tx), (gfloat) ns->tx,
679 &stats_bytes_abbrev[0],
680 sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
681 gkrellm_format_size_abbrev(total, sizeof(total),
682 (gfloat) (ns->rx + ns->tx),
683 &stats_bytes_abbrev[0],
684 sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
685 minutes = ns->connect_time / 60;
686 hours = minutes / 60;
687 minutes %= 60;
688 snprintf(time, sizeof(time), "%4d:%02d", hours, minutes);
689
690 gtk_list_store_append(store, &iter);
691 gtk_list_store_set(store, &iter,
692 DATE_COLUMN, ns->date,
693 RX_COLUMN, rx,
694 TX_COLUMN, tx,
695 TOTAL_COLUMN, total,
696 TIME_COLUMN, time,
697 -1);
698 }
699 return GTK_TREE_MODEL(store);
700 }
701
702 static gint
net_stats_window_configure_cb(GtkWidget * widget,GdkEventConfigure * ev,gpointer data)703 net_stats_window_configure_cb(GtkWidget *widget, GdkEventConfigure *ev,
704 gpointer data)
705 {
706 net_stats_window_height = widget->allocation.height;
707 gkrellm_config_modified();
708 return FALSE;
709 }
710
711 static void
net_stats_close_cb(GtkWidget * widget,GtkWidget * stats_window)712 net_stats_close_cb(GtkWidget *widget, GtkWidget *stats_window)
713 {
714 gtk_widget_destroy(stats_window);
715 }
716
717 static void
net_stats_page(GtkWidget * vbox,NetMon * net,NetStat * ns,gint n_stats,gchar * period)718 net_stats_page(GtkWidget *vbox, NetMon *net,
719 NetStat *ns, gint n_stats, gchar *period)
720 {
721 GtkTreeView *treeview;
722 GtkTreeModel *model;
723 GtkCellRenderer *renderer;
724 gint i;
725
726 model = stats_model_create(net, ns, n_stats);
727 treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
728 g_object_unref(model);
729 gtk_tree_view_set_rules_hint(treeview, TRUE);
730
731 renderer = gtk_cell_renderer_text_new();
732 gtk_tree_view_insert_column_with_attributes(treeview, -1, period,
733 renderer, "text", DATE_COLUMN, NULL);
734
735 renderer = gtk_cell_renderer_text_new();
736 gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Received"),
737 renderer, "text", RX_COLUMN, NULL);
738
739 renderer = gtk_cell_renderer_text_new();
740 gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Transmitted"),
741 renderer, "text", TX_COLUMN, NULL);
742
743 renderer = gtk_cell_renderer_text_new();
744 gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Total"),
745 renderer, "text", TOTAL_COLUMN, NULL);
746
747 for (i = 0; i < n_stats; ++i)
748 if (ns[i].connect_time > 0)
749 {
750 renderer = gtk_cell_renderer_text_new();
751 gtk_tree_view_insert_column_with_attributes(treeview, -1,
752 _("Connect Time"),
753 renderer, "text", TIME_COLUMN, NULL);
754 break;
755 }
756 gkrellm_gtk_scrolled_selection(treeview, vbox,
757 GTK_SELECTION_NONE,
758 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC,
759 NULL, NULL);
760 }
761
762 static void
net_stats_window_show(NetMon * net)763 net_stats_window_show(NetMon *net)
764 {
765 GtkWidget *stats_window, *tabs, *main_vbox;
766 GtkWidget *vbox, *hbox, *button, *sep;
767 gchar buf[64];
768
769 snprintf(buf, sizeof(buf), _("%s Statistics"), net->name);
770
771 stats_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
772 gtk_window_set_title(GTK_WINDOW(stats_window), buf);
773 gtk_window_set_wmclass(GTK_WINDOW(stats_window),
774 "Gkrellm_netstats", "Gkrellm");
775
776 g_signal_connect(G_OBJECT(stats_window), "configure_event",
777 G_CALLBACK(net_stats_window_configure_cb), NULL);
778 gtk_window_set_default_size(GTK_WINDOW(stats_window),
779 -1, net_stats_window_height);
780
781 main_vbox = gtk_vbox_new(FALSE, 0);
782 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 4);
783 gtk_container_add(GTK_CONTAINER(stats_window), main_vbox);
784
785 tabs = gtk_notebook_new();
786 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
787 gtk_box_pack_start(GTK_BOX(main_vbox), tabs, TRUE, TRUE, 0);
788
789 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Daily"));
790 net_stats_page(vbox, net, &net->day_stats[0], N_DAY_STATS, _("Date"));
791
792 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Weekly"));
793 net_stats_page(vbox, net, &net->week_stats[0], N_WEEK_STATS,
794 _("Week Ending"));
795
796 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Monthly"));
797 net_stats_page(vbox, net, &net->month_stats[0], N_MONTH_STATS,
798 _("Month"));
799
800 sep = gtk_hseparator_new();
801 gtk_box_pack_start(GTK_BOX(main_vbox), sep, FALSE, FALSE, 3);
802
803 hbox = gtk_hbutton_box_new();
804 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
805 gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 4);
806 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
807 g_signal_connect(G_OBJECT(button), "clicked",
808 G_CALLBACK(net_stats_close_cb), stats_window);
809 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
810
811 gtk_widget_show_all(stats_window);
812 }
813
814
815 static gint
get_connect_state(void)816 get_connect_state(void)
817 {
818 struct stat st;
819 gchar buf[256];
820 gint state = TB_NORMAL;
821 static gint old_state;
822
823 switch (timer_button_type)
824 {
825 case TIMER_TYPE_NONE:
826 case TIMER_TYPE_SERVER:
827 break;
828 case TIMER_TYPE_PPP:
829 if (net_timed->up)
830 state = TB_ON;
831 else if (lock_directory && *lock_directory)
832 {
833 snprintf(buf, sizeof(buf),
834 "%s/%s", lock_directory, PPP_LOCK_FILE);
835 if (g_stat(buf, &st) == 0)
836 state = TB_STANDBY;
837 else
838 {
839 /* If lock file is ttySx, then user can make a link:
840 | ln -s ~/.gkrellm2/LCK..modem lock_directory/LCK..ttySx
841 */
842 snprintf(buf, sizeof(buf), "%s/%s/%s",
843 gkrellm_homedir(), GKRELLM_DIR, PPP_LOCK_FILE);
844 if (g_stat(buf, &st) == 0)
845 state = TB_STANDBY;
846 }
847 }
848 break;
849 case TIMER_TYPE_IPPP:
850 if (isdn_is_online && (*isdn_is_online)())
851 state = net_timed->up ? TB_ON : TB_STANDBY;
852 break;
853 }
854 if ((_GK.debug_level & DEBUG_TIMER) && state != old_state)
855 g_print(_("get_connect_state changed from %d to %d (check=%d)\n"),
856 old_state, state, check_connect_state);
857 old_state = state;
858 return state;
859 }
860
861 static void
get_connect_time(void)862 get_connect_time(void)
863 {
864 struct stat st;
865 gchar buf[256];
866 time_t t = 0;
867
868 switch (timer_button_type)
869 {
870 case TIMER_TYPE_NONE:
871 case TIMER_TYPE_SERVER:
872 break;
873 case TIMER_TYPE_PPP:
874 snprintf(buf, sizeof(buf), "/var/run/%s.pid", timer_button_iface);
875 if (g_stat(buf, &st) == 0)
876 t = st.st_mtime;
877 break;
878 case TIMER_TYPE_IPPP:
879 break;
880 }
881 if (t > 0)
882 net_timer0 = t;
883 else
884 time(&net_timer0);
885 }
886
887 static void
set_timer_button_state(gint decal_state)888 set_timer_button_state(gint decal_state)
889 {
890 timer_button_old_state = timer_button_state;
891 timer_button_state = decal_state;
892 gkrellm_draw_decal_pixmap(timer_panel, button_decal, decal_state);
893 gkrellm_draw_panel_layers(timer_panel);
894
895 if ( (_GK.debug_level & DEBUG_TIMER)
896 && timer_button_state != timer_button_old_state
897 )
898 g_print(_("set_timer_button_state from %d to %d (check=%d)\n"),
899 timer_button_old_state, timer_button_state, check_connect_state);
900 }
901
902 static void
update_timer_button_monitor(void)903 update_timer_button_monitor(void)
904 {
905 if (timer_button_state == TB_PRESSED)
906 return;
907 if ( (_GK.debug_level & DEBUG_TIMER) && net_timed
908 && timer_button_type != TIMER_TYPE_NONE
909 && (net_timed->up_event || net_timed->down_event)
910 )
911 g_print(_("update_timer_button net_timed old_state=%d new_state=%d\n"),
912 net_timed->up_event, net_timed->down_event);
913 switch (timer_button_type)
914 {
915 case TIMER_TYPE_NONE:
916 if (timer_button_state == TB_ON)
917 draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
918 break;
919
920 case TIMER_TYPE_PPP:
921 if (net_timed->up)
922 {
923 set_timer_button_state(TB_ON);
924 check_connect_state = FALSE;
925 if (net_timed->up_event)
926 get_connect_time();
927 }
928 else if (net_timed->down_event)
929 set_timer_button_state(TB_NORMAL);
930 if (check_connect_state)
931 set_timer_button_state(get_connect_state());
932
933 if (net_timed->up)
934 draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
935 break;
936
937 case TIMER_TYPE_IPPP:
938 /* get all isdn status from get_connect_state because the
939 | net_timed->up can be UP even with isdn line not connected.
940 */
941 set_timer_button_state(get_connect_state());
942 if ( timer_button_state != TB_NORMAL
943 && timer_button_old_state == TB_NORMAL
944 )
945 time(&net_timer0); /* New session just started */
946 if (timer_button_state != TB_NORMAL)
947 draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
948 break;
949
950 case TIMER_TYPE_SERVER:
951 /* Button state is independent of displayed timer
952 */
953 draw_timer(timer_panel, gkrellm_client_server_get_net_timer(), 0);
954 break;
955 }
956 if (net_timed && net_timed->up)
957 {
958 net_timed->day_stats[0].connect_time += 1;
959 net_timed->week_stats[0].connect_time += 1;
960 net_timed->month_stats[0].connect_time += 1;
961 }
962 }
963
964 static void
stale_pppd_files_debug(void)965 stale_pppd_files_debug(void)
966 {
967 struct stat st;
968 gchar buf[256];
969
970 snprintf(buf, sizeof(buf), "/var/run/%s.pid", timer_button_iface);
971 if (g_stat(buf, &st) == 0 && !net_timed->up)
972 g_print(_(" **** Stale pppd pppX.pid file detected!\n"));
973 }
974
975 static gint
in_button(GkrellmDecal * d,GdkEventButton * ev)976 in_button(GkrellmDecal *d, GdkEventButton *ev)
977 {
978 if (ev->x > d->x && ev->x <= d->x + d->w)
979 return TRUE;
980 return FALSE;
981 }
982
983 static gint save_tb_state;
984
985 static gint
cb_timer_button_press(GtkWidget * widget,GdkEventButton * ev)986 cb_timer_button_press(GtkWidget *widget, GdkEventButton *ev)
987 {
988 if (ev->button != 1 || !in_button(DECAL(timer_panel), ev))
989 return FALSE;
990 if (timer_button_state != TB_PRESSED) /* button bounce? */
991 save_tb_state = timer_button_state;
992 set_timer_button_state(TB_PRESSED);
993 return FALSE;
994 }
995
996 static gint
cb_timer_button_release(GtkWidget * widget,GdkEventButton * ev)997 cb_timer_button_release(GtkWidget *widget, GdkEventButton *ev)
998 {
999 gint tstate, timer_command;
1000
1001 if (timer_button_state != TB_PRESSED)
1002 return FALSE;
1003 set_timer_button_state(save_tb_state);
1004 if (! in_button(DECAL(timer_panel), ev))
1005 return FALSE;
1006
1007 switch (timer_button_type)
1008 {
1009 case TIMER_TYPE_NONE:
1010 case TIMER_TYPE_SERVER:
1011 if (timer_button_state == TB_NORMAL)
1012 {
1013 if (*timer_on_command != '\0')
1014 g_spawn_command_line_async(timer_on_command, NULL);
1015 set_timer_button_state(TB_ON);
1016 time(&net_timer0);
1017 }
1018 else
1019 {
1020 if (*timer_off_command != '\0')
1021 g_spawn_command_line_async(timer_off_command, NULL);
1022 set_timer_button_state(TB_NORMAL);
1023 }
1024 break;
1025
1026 case TIMER_TYPE_PPP:
1027 case TIMER_TYPE_IPPP:
1028 check_connect_state = TRUE;
1029 tstate = get_connect_state();
1030 if (_GK.debug_level & DEBUG_TIMER)
1031 stale_pppd_files_debug();
1032 if (tstate == TB_NORMAL)
1033 timer_command = ON;
1034 else if (tstate == TB_ON)
1035 timer_command = OFF;
1036 else /* tstate == TB_STANDBY */
1037 {
1038 /* For some, pppd is leaving stale LCK..modem (and ppp0.pid)
1039 | files which can fool gkrellm. So the question is, do I
1040 | launch off or on command here? Since I can't trust
1041 | TB_STANDBY to mean pppd is running, I'll just base it on
1042 | state info.
1043 */
1044 if (last_timer_command == ON)
1045 {
1046 timer_command = OFF;
1047 if (timer_button_type == TIMER_TYPE_PPP)
1048 set_timer_button_state(TB_NORMAL);
1049 check_connect_state = FALSE;
1050 draw_led(net_timed, RX_LED, RX_OFF); /* Noise */
1051 draw_led(net_timed, TX_LED, TX_OFF);
1052 }
1053 else
1054 timer_command = ON;
1055 }
1056 if (timer_command == ON && *timer_on_command != '\0')
1057 g_spawn_command_line_async(timer_on_command, NULL);
1058 if (timer_command == OFF && *timer_off_command != '\0')
1059 g_spawn_command_line_async(timer_off_command, NULL);
1060 last_timer_command = timer_command;
1061 break;
1062 }
1063 return FALSE;
1064 }
1065
1066
1067 /* A timed_net (linked to the timer button) always has a panel
1068 | visible, and the Chart visibility is toggled based on net up state.
1069 */
1070 static void
timed_net_visibility(void)1071 timed_net_visibility(void)
1072 {
1073 NetMon *net = net_timed;
1074 gboolean net_is_up,
1075 chart_is_visible;
1076
1077 if (!net || !net->chart)
1078 return;
1079 chart_is_visible = gkrellm_is_chart_visible(net->chart);
1080
1081 /* For ippp, the route may always be up, so base a up state on the
1082 | route being alive and the line status being connected (timer button
1083 | state)
1084 */
1085 if (timer_button_type == TIMER_TYPE_IPPP)
1086 net_is_up = (net->up && timer_button_state != TB_NORMAL);
1087 else
1088 net_is_up = net->up;
1089
1090 if ((net->force_up || net_is_up) && !chart_is_visible)
1091 gkrellm_chart_show(net->chart, TRUE); /* Make sure panel is shown */
1092 else if (!net->force_up && !net_is_up && chart_is_visible)
1093 {
1094 gkrellm_chart_hide(net->chart, FALSE); /* Don't hide the panel */
1095
1096 /* Save data whenever net has transitioned to a "not up" state.
1097 | Don't have the info to do this when there's a force_up and in
1098 | this case just rely on the every six hour tick data save.
1099 */
1100 gkrellm_net_save_data();
1101 }
1102 }
1103
1104
1105 static gint
net_expose_event(GtkWidget * widget,GdkEventExpose * ev)1106 net_expose_event(GtkWidget *widget, GdkEventExpose *ev)
1107 {
1108 GList *list;
1109 NetMon *net;
1110 GdkPixmap *pixmap = NULL;
1111
1112 if (timer_panel->drawing_area == widget)
1113 pixmap = timer_panel->pixmap;
1114 else
1115 for (list = net_mon_list; list; list = list->next)
1116 {
1117 net = (NetMon *) list->data;
1118 if (!net->chart || !net->chart->panel) /* A disabled iface */
1119 continue;
1120 if (net->chart->drawing_area == widget)
1121 pixmap = net->chart->pixmap;
1122 else if (net->chart->panel->drawing_area == widget)
1123 pixmap = net->chart->panel->pixmap;
1124 if (pixmap)
1125 break;
1126 }
1127 if (pixmap)
1128 gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), pixmap,
1129 ev->area.x, ev->area.y, ev->area.x, ev->area.y,
1130 ev->area.width, ev->area.height);
1131 return FALSE;
1132 }
1133
1134 static gint
map_x(gint x,gint width)1135 map_x(gint x, gint width)
1136 {
1137 gint xnew, chart_width;
1138
1139 xnew = x;
1140 chart_width = gkrellm_chart_width();
1141 if (x < 0)
1142 xnew += chart_width - width;
1143 return xnew;
1144 }
1145
1146 static gint
grid_resolution_default(NetMon * net)1147 grid_resolution_default(NetMon *net)
1148 {
1149 gchar *s = net->name;
1150 gint res;
1151
1152 if (! strncmp(s, "ppp", 3))
1153 res = 2000;
1154 #if defined(__FreeBSD__)
1155 else if (! strncmp(s, "tun", 3))
1156 res = 2000;
1157 #endif
1158 else if (! strncmp(s, "plip", 3) || ! strncmp(s, "ippp", 4))
1159 res = 5000;
1160 else if (! strncmp(s, "eth", 3))
1161 res = 20000;
1162 else
1163 res = 10000;
1164 return res;
1165 }
1166
1167 static void
setup_net_scaling(GkrellmChartconfig * cf,NetMon * net)1168 setup_net_scaling(GkrellmChartconfig *cf, NetMon *net)
1169 {
1170 GkrellmChart *cp = net->chart;
1171 gint grids, res;
1172
1173 grids = gkrellm_get_chartconfig_fixed_grids(cf);
1174 if (!grids)
1175 grids = FULL_SCALE_GRIDS;
1176
1177 res = gkrellm_get_chartconfig_grid_resolution(cf);
1178 KRELL(cp->panel)->full_scale = res * grids / gkrellm_update_HZ();
1179 }
1180
1181 static void
destroy_chart(NetMon * net)1182 destroy_chart(NetMon *net)
1183 {
1184 GkrellmChart *cp;
1185
1186 if (!net)
1187 return;
1188 cp = net->chart;
1189 if (cp)
1190 {
1191 net->launch.button = NULL;
1192 g_free(cp->panel->textstyle);
1193 cp->panel->textstyle = NULL;
1194 gkrellm_chart_destroy(cp);
1195 gtk_widget_destroy(net->vbox);
1196 net->chart = NULL;
1197 net->vbox = NULL;
1198 net->parent_vbox = NULL;
1199 }
1200 net->locked = FALSE;
1201 }
1202
1203
1204 static GkrellmSizeAbbrev current_bytes_abbrev[] =
1205 {
1206 { KB_SIZE(1), 1, "%.0f" },
1207 { KB_SIZE(20), KB_SIZE(1), "%.1fK" },
1208 { MB_SIZE(1), KB_SIZE(1), "%.0fK" },
1209 { MB_SIZE(20), MB_SIZE(1), "%.1fM" },
1210 { GB_SIZE(1), MB_SIZE(1), "%.0fM" },
1211 { GB_SIZE(20), GB_SIZE(1), "%.1fG" },
1212 { TB_SIZE(1), GB_SIZE(1), "%.0fG" },
1213 { TB_SIZE(20), TB_SIZE(1), "%.1fT" },
1214 { TB_SIZE(1000), TB_SIZE(1), "%.0fT" }
1215 };
1216
1217 static GkrellmSizeAbbrev total_bytes_abbrev[] =
1218 {
1219 { KB_SIZE(100), 1, "%.0f" },
1220 { MB_SIZE(1), KB_SIZE(1), "%.1fK" },
1221 { MB_SIZE(10), MB_SIZE(1), "%.3fM" },
1222 { MB_SIZE(100), MB_SIZE(1), "%.2fM" },
1223 { GB_SIZE(1), MB_SIZE(1), "%.1fM" },
1224 { GB_SIZE(10), GB_SIZE(1), "%.3fG" },
1225 { GB_SIZE(100), GB_SIZE(1), "%.2fG" },
1226 { TB_SIZE(1), GB_SIZE(1), "%.1fG" },
1227 { TB_SIZE(10), TB_SIZE(1), "%.3fT" },
1228 { TB_SIZE(100), TB_SIZE(1), "%.2fT" },
1229 { TB_SIZE(1000), TB_SIZE(1), "%.1fT" }
1230 };
1231
1232 #define DEFAULT_TEXT_FORMAT "$T\\b\\c\\f$L"
1233
1234 static gchar *text_format,
1235 *text_format_locale;
1236
1237 static void
format_net_data(NetMon * net,gchar * src_string,gchar * buf,gint size)1238 format_net_data(NetMon *net, gchar *src_string, gchar *buf, gint size)
1239 {
1240 GkrellmChart *cp;
1241 gchar c, *s, *s1, *result;
1242 gint len, bytes;
1243 gdouble fbytes;
1244 gboolean month, day, week;
1245
1246 if (!buf || size < 1)
1247 return;
1248 --size;
1249 *buf = '\0';
1250 result = buf;
1251
1252 if (!src_string)
1253 return;
1254 cp = net->chart;
1255 net->totals_shown = FALSE;
1256
1257 gkrellm_debug(DEBUG_CHART_TEXT, "net chart text: %s\n", src_string);
1258
1259 for (s = src_string; *s != '\0' && size > 0; ++s)
1260 {
1261 len = 1;
1262 month = week = day = FALSE;
1263 if (*s == '$' && *(s + 1) != '\0')
1264 {
1265 bytes = -1;
1266 fbytes = -1.0;
1267 if ((c = *(s + 2)) == 'm') /* cumulative modifiers */
1268 month = TRUE;
1269 else if (c == 'w')
1270 week = TRUE;
1271 else if (c == 'd')
1272 day = TRUE;
1273
1274 if ((c = *(s + 1)) == 'T')
1275 bytes = net->rx_current + net->tx_current;
1276 else if (c == 'M')
1277 bytes = gkrellm_get_chart_scalemax(cp);
1278 else if (c == 't')
1279 bytes = net->tx_current;
1280 else if (c == 'r')
1281 bytes = net->rx_current;
1282 else if (c == 'o')
1283 {
1284 if (month)
1285 fbytes = net->month_stats[0].tx;
1286 else if (week)
1287 fbytes = net->week_stats[0].tx;
1288 else if (day)
1289 fbytes = net->day_stats[0].tx;
1290 else
1291 fbytes = net->show_totalB
1292 ? net->tx_totalB : net->tx_totalA;
1293 }
1294 else if (c == 'i')
1295 {
1296 if (month)
1297 fbytes = net->month_stats[0].rx;
1298 else if (week)
1299 fbytes = net->week_stats[0].rx;
1300 else if (day)
1301 fbytes = net->day_stats[0].rx;
1302 else
1303 fbytes = net->show_totalB
1304 ? net->rx_totalB : net->rx_totalA;
1305 }
1306 else if (c == 'O')
1307 {
1308 if (month)
1309 fbytes = net->month_stats[0].rx + net->month_stats[0].tx;
1310 else if (week)
1311 fbytes = net->week_stats[0].rx + net->week_stats[0].tx;
1312 else if (day)
1313 fbytes = net->day_stats[0].rx + net->day_stats[0].tx;
1314 else
1315 fbytes = net->show_totalB
1316 ? (net->rx_totalB + net->tx_totalB)
1317 : (net->rx_totalA + net->tx_totalA);
1318 }
1319 else if (c == 'L')
1320 {
1321 if (!*(net->label))
1322 s1 = " ";
1323 else
1324 s1 = net->label;
1325 len = snprintf(buf, size, "%s", s1);
1326 }
1327 else if (c == 'I')
1328 len = snprintf(buf, size, "%s", net->name);
1329 else if (c == 'H')
1330 len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name());
1331 else if ((s1 = gkrellm_plugin_get_exported_label(mon_net, c,
1332 net->name)) != NULL)
1333 len = snprintf(buf, size, "%s", s1);
1334 else
1335 {
1336 *buf = *s;
1337 if (size > 1)
1338 {
1339 *(buf + 1) = *(s + 1);
1340 ++len;
1341 }
1342 }
1343 if (bytes >= 0)
1344 len = gkrellm_format_size_abbrev(buf, size, (gfloat) bytes,
1345 ¤t_bytes_abbrev[0],
1346 sizeof(current_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
1347 else if (fbytes >= 0)
1348 {
1349 len = gkrellm_format_size_abbrev(buf, size, (gfloat) fbytes,
1350 &total_bytes_abbrev[0],
1351 sizeof(total_bytes_abbrev) /sizeof(GkrellmSizeAbbrev));
1352 if (!day && !week && !month)
1353 net->totals_shown = TRUE;
1354 }
1355 ++s;
1356 if (day || week || month)
1357 ++s;
1358 }
1359 else
1360 *buf = *s;
1361 size -= len;
1362 buf += len;
1363 }
1364 *buf = '\0';
1365
1366 gkrellm_debug(DEBUG_CHART_TEXT, " : %s\n", result);
1367 }
1368
1369 static void
draw_net_chart_labels(NetMon * net)1370 draw_net_chart_labels(NetMon *net)
1371 {
1372 GkrellmChart *cp = net->chart;
1373 gchar buf[128];
1374
1375 if (!net->chart_labels)
1376 return;
1377 format_net_data(net, text_format_locale, buf, sizeof(buf));
1378 if (!net->new_text_format)
1379 gkrellm_chart_reuse_text_format(cp);
1380 net->new_text_format = FALSE;
1381 gkrellm_draw_chart_text(cp, net_style_id, buf);
1382 }
1383
1384 static void
cb_command_process(GkrellmAlert * alert,gchar * src,gchar * dst,gint len,NetMon * net)1385 cb_command_process(GkrellmAlert *alert, gchar *src, gchar *dst, gint len,
1386 NetMon *net)
1387 {
1388 format_net_data(net, src, dst, len);
1389 }
1390
1391 static void
draw_chart_buttons(NetMon * net)1392 draw_chart_buttons(NetMon *net)
1393 {
1394 gint frame, x, y;
1395
1396 if ( net->totals_shown && net->chart_labels
1397 && decal_totalA && decal_totalB && decal_reset
1398 )
1399 {
1400 x = gkrellm_chart_width() - 2 * decal_totalA->w;
1401 y = 2;
1402
1403 frame = net->show_totalB ? D_MISC_BUTTON_OUT : D_MISC_BUTTON_IN;
1404 gkrellm_draw_decal_pixmap(NULL, decal_totalA, frame);
1405 gkrellm_draw_decal_on_chart(net->chart, decal_totalA, x, y);
1406
1407 frame = net->show_totalB ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
1408 gkrellm_draw_decal_pixmap(NULL, decal_totalB, frame);
1409 gkrellm_draw_decal_on_chart(net->chart, decal_totalB,
1410 x + decal_totalA->w, y);
1411
1412 frame = net->reset_button_in ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
1413 gkrellm_draw_decal_pixmap(NULL, decal_reset, frame);
1414 gkrellm_draw_decal_on_chart(net->chart, decal_reset,
1415 x + decal_totalA->w, y + decal_totalA->h + 4);
1416 }
1417 if (decal_stats)
1418 {
1419 x = gkrellm_chart_width() - decal_stats->w;
1420 y = net->chart->h - decal_stats->h;
1421 frame = net->stats_button_in ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
1422 gkrellm_draw_decal_pixmap(NULL, decal_stats, frame);
1423 gkrellm_draw_decal_on_chart(net->chart, decal_stats, x, y);
1424 }
1425 }
1426
1427 static void
refresh_net_chart(NetMon * net)1428 refresh_net_chart(NetMon *net)
1429 {
1430 if (!net->chart)
1431 return;
1432 gkrellm_draw_chartdata(net->chart);
1433 draw_net_chart_labels(net);
1434 if (net->mouse_in_chart)
1435 draw_chart_buttons(net);
1436 gkrellm_draw_chart_to_screen(net->chart);
1437 }
1438
1439
1440 static gint
cb_chart_press(GtkWidget * widget,GdkEventButton * ev,NetMon * net)1441 cb_chart_press(GtkWidget *widget, GdkEventButton *ev, NetMon *net)
1442 {
1443 gboolean check_button;
1444
1445 check_button = net->chart_labels && net->totals_shown;
1446 if (check_button && gkrellm_in_decal(decal_totalA, ev))
1447 {
1448 net->show_totalB = FALSE;
1449 refresh_net_chart(net);
1450 }
1451 else if (check_button && gkrellm_in_decal(decal_totalB, ev))
1452 {
1453 net->show_totalB = TRUE;
1454 refresh_net_chart(net);
1455 }
1456 else if (check_button && gkrellm_in_decal(decal_reset, ev))
1457 {
1458 net->reset_button_in = TRUE;
1459 refresh_net_chart(net);
1460 }
1461 else if (gkrellm_in_decal(decal_stats, ev))
1462 {
1463 net->stats_button_in = TRUE;
1464 refresh_net_chart(net);
1465 }
1466 else if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
1467 {
1468 net->chart_labels = !net->chart_labels;
1469 gkrellm_config_modified();
1470 refresh_net_chart(net);
1471 }
1472 else if ( ev->button == 3
1473 || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS)
1474 )
1475 gkrellm_chartconfig_window_create(net->chart);
1476
1477 return FALSE;
1478 }
1479
1480 static gint
cb_chart_release(GtkWidget * widget,GdkEventButton * ev,NetMon * net)1481 cb_chart_release(GtkWidget *widget, GdkEventButton *ev, NetMon *net)
1482 {
1483 if (!net->reset_button_in && !net->stats_button_in)
1484 return FALSE;
1485 if (net->stats_button_in && gkrellm_in_decal(decal_stats, ev))
1486 net_stats_window_show(net);
1487 if (net->reset_button_in && gkrellm_in_decal(decal_reset, ev))
1488 {
1489 if (net->show_totalB)
1490 net->rx_totalB = net->tx_totalB = 0;
1491 else
1492 net->rx_totalA = net->tx_totalA = 0;
1493 }
1494 net->reset_button_in = FALSE;
1495 net->stats_button_in = FALSE;
1496 refresh_net_chart(net);
1497 return FALSE;
1498 }
1499
1500 static gint
cb_chart_enter(GtkWidget * w,GdkEventButton * ev,NetMon * net)1501 cb_chart_enter(GtkWidget *w, GdkEventButton *ev, NetMon *net)
1502 {
1503 net->mouse_in_chart = TRUE;
1504 draw_chart_buttons(net);
1505 gkrellm_draw_chart_to_screen(net->chart);
1506 return FALSE;
1507 }
1508
1509 static gint
cb_chart_leave(GtkWidget * w,GdkEventButton * ev,NetMon * net)1510 cb_chart_leave(GtkWidget *w, GdkEventButton *ev, NetMon *net)
1511 {
1512 net->mouse_in_chart = FALSE;
1513 net->reset_button_in = FALSE;
1514 net->stats_button_in = FALSE;
1515 refresh_net_chart(net);
1516 return FALSE;
1517 }
1518
1519 static gint
cb_panel_press(GtkWidget * widget,GdkEventButton * ev)1520 cb_panel_press(GtkWidget *widget, GdkEventButton *ev)
1521 {
1522 if (ev->button == 3)
1523 gkrellm_open_config_window(mon_net);
1524 return FALSE;
1525 }
1526
1527 /* Make sure net charts appear in same order as the sorted net_mon_list
1528 */
1529 static void
net_chart_reorder(NetMon * new_net)1530 net_chart_reorder(NetMon *new_net)
1531 {
1532 NetMon *net;
1533 GList *list;
1534 gint i;
1535
1536 for (i = 0, list = net_mon_list; list; list = list->next)
1537 {
1538 net = (NetMon *) list->data;
1539 if (net->parent_vbox != new_net->parent_vbox)
1540 continue;
1541 if (net == new_net)
1542 break;
1543 ++i;
1544 }
1545 if (!list || !list->next)
1546 return;
1547 gtk_box_reorder_child(GTK_BOX(new_net->parent_vbox), new_net->vbox, i);
1548 }
1549
1550 static void
create_net_monitor(GtkWidget * vbox,NetMon * net,gint first_create)1551 create_net_monitor(GtkWidget *vbox, NetMon *net, gint first_create)
1552 {
1553 GkrellmStyle *style;
1554 GkrellmChart *cp;
1555 GkrellmPanel *p;
1556
1557 if (first_create)
1558 {
1559 net->parent_vbox = vbox;
1560 net->vbox = gtk_vbox_new(FALSE, 0);
1561 gtk_box_pack_start(GTK_BOX(vbox), net->vbox, FALSE, FALSE, 0);
1562
1563 net->chart = gkrellm_chart_new0();
1564 net->chart->panel = gkrellm_panel_new0();
1565 net->chart->panel->textstyle = gkrellm_textstyle_new0();
1566 net_chart_reorder(net);
1567 }
1568 cp = net->chart;
1569 p = cp->panel;
1570
1571 gkrellm_chart_create(net->vbox, mon_net, cp, &net->chart_config);
1572 net->tx_cd = gkrellm_add_default_chartdata(cp, _("tx bytes"));
1573 net->rx_cd = gkrellm_add_default_chartdata(cp, _("rx bytes"));
1574 gkrellm_set_draw_chart_function(cp, refresh_net_chart, net);
1575
1576 gkrellm_chartconfig_fixed_grids_connect(cp->config,
1577 setup_net_scaling, net);
1578 gkrellm_chartconfig_grid_resolution_connect(cp->config,
1579 setup_net_scaling, net);
1580 gkrellm_chartconfig_grid_resolution_adjustment(cp->config, TRUE,
1581 0, (gfloat) MIN_GRID_RES, (gfloat) MAX_GRID_RES, 0, 0, 0, 0);
1582
1583 gkrellm_chartconfig_grid_resolution_label(cp->config,
1584 _("rx/tx bytes per sec"));
1585 if (gkrellm_get_chartconfig_grid_resolution(cp->config) < MIN_GRID_RES)
1586 gkrellm_set_chartconfig_grid_resolution(cp->config,
1587 grid_resolution_default(net));
1588 gkrellm_alloc_chartdata(cp);
1589
1590 style = gkrellm_panel_style(net_style_id);
1591 gkrellm_create_krell(p, gkrellm_krell_panel_piximage(net_style_id), style);
1592
1593 net->rxled = gkrellm_create_decal_pixmap(p, decal_net_led_pixmap,
1594 decal_net_led_mask, N_LEDS, style, 0, _GK.rx_led_y);
1595 net->rxled->x = map_x(_GK.rx_led_x, net->rxled->w);
1596
1597 net->txled = gkrellm_create_decal_pixmap(p, decal_net_led_pixmap,
1598 decal_net_led_mask, N_LEDS, style, 0, _GK.tx_led_y);
1599 net->txled->x = map_x(_GK.tx_led_x, net->txled->w);
1600
1601 *(p->textstyle) = *gkrellm_panel_textstyle(net_style_id);
1602 if (strlen(net->name) > 5)
1603 p->textstyle->font = gkrellm_panel_alt_textstyle(net_style_id)->font;
1604
1605 gkrellm_panel_configure(p, net->name, style);
1606 gkrellm_panel_create(net->vbox, mon_net, p);
1607
1608 setup_net_scaling(cp->config, net);
1609
1610 net->new_text_format = TRUE;
1611 if (first_create)
1612 {
1613 g_signal_connect(G_OBJECT (cp->drawing_area), "expose_event",
1614 G_CALLBACK(net_expose_event), NULL);
1615 g_signal_connect(G_OBJECT(cp->drawing_area), "button_press_event",
1616 G_CALLBACK(cb_chart_press), net);
1617 g_signal_connect(G_OBJECT(cp->drawing_area), "button_release_event",
1618 G_CALLBACK(cb_chart_release), net);
1619 g_signal_connect(G_OBJECT(cp->drawing_area), "enter_notify_event",
1620 G_CALLBACK(cb_chart_enter), net);
1621 g_signal_connect(G_OBJECT(cp->drawing_area), "leave_notify_event",
1622 G_CALLBACK(cb_chart_leave), net);
1623
1624 g_signal_connect(G_OBJECT (p->drawing_area), "expose_event",
1625 G_CALLBACK(net_expose_event), NULL);
1626 g_signal_connect(G_OBJECT(p->drawing_area), "button_press_event",
1627 G_CALLBACK(cb_panel_press), NULL);
1628
1629 gtk_widget_show_all(net->vbox);
1630 }
1631 else
1632 refresh_net_chart(net);
1633
1634 gkrellm_setup_launcher(p, &net->launch, CHART_PANEL_TYPE, 0);
1635
1636 draw_led(net, RX_LED, RX_OFF);
1637 draw_led(net, TX_LED, TX_OFF);
1638
1639 if (net->force_up)
1640 net->locked = TRUE;
1641 }
1642
1643 static void
net_timer_visibility(void)1644 net_timer_visibility(void)
1645 {
1646 if (timer_button_enabled)
1647 {
1648 gkrellm_panel_show(timer_panel);
1649 gkrellm_spacers_show(mon_timer);
1650 }
1651 else
1652 {
1653 gkrellm_panel_hide(timer_panel);
1654 gkrellm_spacers_hide(mon_timer);
1655 }
1656 }
1657
1658
1659 static gint
days_in_year(gint y)1660 days_in_year(gint y)
1661 {
1662 if((y % 4) == 0)
1663 return 366;
1664 return 365;
1665 }
1666
1667 /* Adjust a tm date structure to reference its next day.
1668 */
1669 static void
next_day(struct tm * t)1670 next_day(struct tm *t)
1671 {
1672 if ((t->tm_wday += 1) > SATURDAY)
1673 t->tm_wday = SUNDAY;
1674 if ((t->tm_yday += 1) >= days_in_year(t->tm_year) )
1675 {
1676 t->tm_year += 1;
1677 t->tm_yday = 0;
1678 }
1679 if ((t->tm_mday += 1) > days_in_month[t->tm_mon])
1680 {
1681 if ( t->tm_mon == 1
1682 && (((gint)t->tm_year - 80) % 4) == 0
1683 && t->tm_mday == 29)
1684 ;
1685 else
1686 {
1687 if ((t->tm_mon += 1) > 11)
1688 t->tm_mon = 0;
1689 t->tm_mday = 1;
1690 }
1691 }
1692 }
1693
1694 static gboolean
net_accounting_month_new(struct tm * tm)1695 net_accounting_month_new(struct tm *tm)
1696 {
1697 if ( tm->tm_mday == reset_mday
1698 || ( reset_mday > days_in_month[tm->tm_mon]
1699 && tm->tm_mday == 1
1700 )
1701 )
1702 return TRUE;
1703 return FALSE;
1704 }
1705
1706 void
gkrellm_net_save_data(void)1707 gkrellm_net_save_data(void)
1708 {
1709 FILE *f;
1710 GList *list;
1711 struct tm *tm = gkrellm_get_current_time();
1712 NetMon *net;
1713 gchar fname[256];
1714 gint i;
1715
1716 for (list = net_mon_list; list; list = list->next)
1717 {
1718 net = (NetMon *) list->data;
1719 if (!net->enabled)
1720 continue;
1721 snprintf(fname, sizeof(fname), "%s%c%s", net_data_dir,
1722 G_DIR_SEPARATOR, net->name);
1723 if ((f = g_fopen(fname, "w")) == NULL)
1724 continue;
1725 fprintf(f, "%d\n", NET_DATA_VERSION);
1726 fputs("wday mday month yday year\n", f);
1727 fprintf(f, "%d %d %d %d %d\n", tm->tm_wday,
1728 tm->tm_mday, tm->tm_mon, tm->tm_yday, tm->tm_year);
1729
1730 fputs("[daily]\n", f);
1731 for (i = 0; i < N_DAY_STATS; ++i)
1732 fprintf(f, "\"%s\" %.0f %.0f %d\n", net->day_stats[i].date,
1733 net->day_stats[i].rx, net->day_stats[i].tx,
1734 net->day_stats[i].connect_time);
1735 fputs("[weekly]\n", f);
1736 for (i = 0; i < N_WEEK_STATS; ++i)
1737 fprintf(f, "\"%s\" %.0f %.0f %d\n", net->week_stats[i].date,
1738 net->week_stats[i].rx, net->week_stats[i].tx,
1739 net->week_stats[i].connect_time);
1740 fputs("[monthly]\n", f);
1741 for (i = 0; i < N_MONTH_STATS; ++i)
1742 fprintf(f, "\"%s\" %.0f %.0f %d\n", net->month_stats[i].date,
1743 net->month_stats[i].rx, net->month_stats[i].tx,
1744 net->month_stats[i].connect_time);
1745 fclose(f);
1746 }
1747 }
1748
1749 static gchar *
utf8_string(gchar * string)1750 utf8_string(gchar *string)
1751 {
1752 gchar *utf8 = NULL;
1753
1754 if ( g_utf8_validate(string, -1, NULL)
1755 || (utf8 = g_locale_to_utf8(string, -1, NULL, NULL, NULL)) == NULL
1756 )
1757 utf8 = g_strdup(string);
1758
1759 return utf8;
1760 }
1761
1762 static void
net_stat_set_date_string(NetStat * ns,enum StatType stat_type,struct tm * t)1763 net_stat_set_date_string(NetStat *ns, enum StatType stat_type, struct tm *t)
1764 {
1765 struct tm tm = *t,
1766 tmx;
1767 gchar *utf8, buf[128], bufa[32], bufb[32];
1768
1769 if (stat_type == DAY_STAT)
1770 {
1771 strftime(buf, sizeof(buf), GK_NET_ISO_DATE, &tm);
1772 }
1773 else if (stat_type == WEEK_STAT)
1774 {
1775 while (tm.tm_wday != SATURDAY)
1776 next_day(&tm);
1777 strftime(buf, sizeof(buf), GK_NET_ISO_DATE, &tm);
1778 }
1779 else if (stat_type == MONTH_STAT)
1780 {
1781 if (reset_mday == 1)
1782 strftime(buf, sizeof(buf), "%B", &tm); /* full month name */
1783 else
1784 {
1785 tmx = tm;
1786 if (tm.tm_mday < reset_mday)
1787 {
1788 tmx.tm_mon -= 1;
1789 if (tmx.tm_mon < 0)
1790 {
1791 tmx.tm_mon = 11;
1792 tmx.tm_year -= 1;
1793 }
1794 }
1795 else
1796 {
1797 tm.tm_mon += 1;
1798 if (tm.tm_mon > 11)
1799 {
1800 tm.tm_mon = 0;
1801 tm.tm_year += 1;
1802 }
1803 }
1804 tmx.tm_mday = reset_mday;
1805 tm.tm_mday = reset_mday - 1;
1806 if (tmx.tm_mday > days_in_month[tmx.tm_mon])
1807 tmx.tm_mday = days_in_month[tmx.tm_mon];
1808 if (tm.tm_mday > days_in_month[tm.tm_mon])
1809 tm.tm_mday = days_in_month[tm.tm_mon];
1810 strftime(bufa, sizeof(bufa), GK_NET_MONTH_STAT_DATE, &tmx);
1811 strftime(bufb, sizeof(bufb), GK_NET_MONTH_STAT_DATE, &tm);
1812 snprintf(buf, sizeof(buf), "%s - %s", bufa, bufb);
1813 }
1814 }
1815 else
1816 return;
1817
1818 g_free(ns->date);
1819 utf8 = utf8_string(buf);
1820 ns->date = utf8 ? utf8 : g_strdup("??");
1821 }
1822
1823 static void
net_stat_init(NetMon * net)1824 net_stat_init(NetMon *net)
1825 {
1826 struct tm *tm = gkrellm_get_current_time();
1827 gint i;
1828
1829 for (i = 0; i < N_DAY_STATS; ++i)
1830 net->day_stats[i].date = g_strdup("---");
1831 for (i = 0; i < N_WEEK_STATS; ++i)
1832 net->week_stats[i].date = g_strdup("---");
1833 for (i = 0; i < N_MONTH_STATS; ++i)
1834 net->month_stats[i].date = g_strdup("---");
1835
1836 net_stat_set_date_string(&net->day_stats[0], DAY_STAT, tm);
1837 net_stat_set_date_string(&net->week_stats[0], WEEK_STAT, tm);
1838 net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, tm);
1839 }
1840
1841 static void
net_stats_shift_down(NetStat * ns,gint n_stats,enum StatType stat_type)1842 net_stats_shift_down(NetStat *ns, gint n_stats, enum StatType stat_type)
1843 {
1844 gint d;
1845
1846 g_free(ns[n_stats - 1].date);
1847
1848 for (d = n_stats - 1; d > 0; --d)
1849 ns[d] = ns[d - 1];
1850 ns->rx = ns->tx = 0.0;
1851 ns->connect_time = 0;
1852 ns->date = NULL;
1853 net_stat_set_date_string(ns, stat_type, gkrellm_get_current_time());
1854 }
1855
1856 static void
load_net_data(void)1857 load_net_data(void)
1858 {
1859 FILE *f;
1860 GList *list;
1861 struct tm *tm = gkrellm_get_current_time();
1862 NetMon *net;
1863 NetStat *ns = NULL;
1864 gchar buf[128], fname[256], date[32];
1865 gint wday, mday, month, yday, year, version;
1866 gint day_delta, month_delta, n_stats = 0;
1867
1868 for (list = net_mon_list; list; list = list->next)
1869 {
1870 net = (NetMon *) list->data;
1871 snprintf(fname, sizeof(fname), "%s%c%s", net_data_dir,
1872 G_DIR_SEPARATOR, net->name);
1873 if ((f = g_fopen(fname, "r")) == NULL)
1874 continue;
1875 fgets(buf, sizeof(buf), f);
1876 if (sscanf(buf, "%d\n", &version) != 1)
1877 {
1878 fclose(f);
1879 continue;
1880 }
1881
1882 fgets(buf, sizeof(buf), f); /* Comment line */
1883 fgets(buf, sizeof(buf), f);
1884 sscanf(buf, "%d %d %d %d %d", &wday, &mday, &month, &yday, &year);
1885
1886 if (version == 1)
1887 {
1888 struct tm tmx = *gkrellm_get_current_time();
1889
1890 tmx.tm_wday = wday;
1891 tmx.tm_mday = mday;
1892 tmx.tm_mon = month;
1893 tmx.tm_yday = yday;
1894 tmx.tm_year = year;
1895
1896 fgets(buf, sizeof(buf), f); /* day */
1897 fgets(buf, sizeof(buf), f);
1898 sscanf(buf, "%lf %lf",
1899 &net->day_stats[0].rx, &net->day_stats[0].tx);
1900 fgets(buf, sizeof(buf), f); /* week */
1901 fgets(buf, sizeof(buf), f);
1902 sscanf(buf, "%lf %lf",
1903 &net->week_stats[0].rx, &net->week_stats[0].tx);
1904 fgets(buf, sizeof(buf), f); /* month */
1905 fgets(buf, sizeof(buf), f);
1906 sscanf(buf, "%lf %lf",
1907 &net->month_stats[0].rx, &net->month_stats[0].tx);
1908
1909 net_stat_set_date_string(&net->day_stats[0], DAY_STAT, &tmx);
1910 net_stat_set_date_string(&net->week_stats[0], WEEK_STAT, &tmx);
1911 net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, &tmx);
1912
1913 if ( net == net_timed
1914 && fgets(buf, sizeof(buf), f) /* connect day*/
1915 )
1916 {
1917 fgets(buf, sizeof(buf), f);
1918 sscanf(buf, "%d %d %d",
1919 &net->day_stats[0].connect_time,
1920 &net->week_stats[0].connect_time,
1921 &net->month_stats[0].connect_time);
1922 }
1923
1924 }
1925 else if (version == NET_DATA_VERSION)
1926 {
1927 while (fgets(buf, sizeof(buf), f) != NULL)
1928 {
1929 if (!strncmp(buf, "[daily]", 7))
1930 {
1931 ns = &net->day_stats[0];
1932 n_stats = N_DAY_STATS;
1933 }
1934 else if (!strncmp(buf, "[weekly]", 8))
1935 {
1936 ns = &net->week_stats[0];
1937 n_stats = N_WEEK_STATS;
1938 }
1939 else if (!strncmp(buf, "[monthly]", 9))
1940 {
1941 ns = &net->month_stats[0];
1942 n_stats = N_MONTH_STATS;
1943 }
1944 else if ( ns && n_stats > 0
1945 && sscanf(buf, "\"%31[^\"]\" %lf %lf %d",
1946 date, &ns->rx, &ns->tx, &ns->connect_time) == 4
1947 )
1948 {
1949 gkrellm_dup_string(&ns->date, date);
1950 ++ns;
1951 --n_stats;
1952 }
1953 }
1954 }
1955 else
1956 {
1957 fclose(f);
1958 continue;
1959 }
1960
1961 fclose(f);
1962
1963 month_delta = (tm->tm_year * 12 + tm->tm_mon) - (year * 12 + month);
1964 if (month_delta == 0)
1965 day_delta = tm->tm_mday - mday;
1966 else if (month_delta == 1)
1967 day_delta = days_in_month[month] - mday + tm->tm_mday;
1968 else
1969 day_delta = 7; /* max compared to is 6 */
1970
1971 if (day_delta > 0)
1972 net_stats_shift_down(&net->day_stats[0], N_DAY_STATS, DAY_STAT);
1973
1974 if (wday + day_delta != tm->tm_wday)
1975 net_stats_shift_down(&net->week_stats[0], N_WEEK_STATS, WEEK_STAT);
1976
1977 if ( ( tm->tm_mday < reset_mday
1978 && ( (month_delta > 1)
1979 || (month_delta == 1 && mday < reset_mday)
1980 )
1981 )
1982 || ( tm->tm_mday >= reset_mday
1983 && ( (month_delta > 0)
1984 || (month_delta == 0 && mday < reset_mday)
1985 )
1986 )
1987 )
1988 net_stats_shift_down(&net->month_stats[0], N_MONTH_STATS,
1989 MONTH_STAT);
1990 }
1991 }
1992
1993
1994 #define SEC_PAD 0
1995
1996 static void
create_net_timer(GtkWidget * vbox,gint first_create)1997 create_net_timer(GtkWidget *vbox, gint first_create)
1998 {
1999 GkrellmPanel *p;
2000 GkrellmStyle *style;
2001 GkrellmTextstyle *ts, *ts_alt;
2002 GkrellmMargin *m;
2003 GkrellmBorder *tb;
2004 gint top_margin, bot_margin;
2005 gint x, y, w, h, w_avail;
2006
2007 if (first_create)
2008 timer_panel = gkrellm_panel_new0();
2009 p = timer_panel;
2010
2011 style = gkrellm_meter_style(timer_style_id);
2012 ts = gkrellm_meter_textstyle(timer_style_id);
2013 ts_alt = gkrellm_meter_alt_textstyle(timer_style_id);
2014 m = gkrellm_get_style_margins(style);
2015 tb = &bg_timer_style->border;
2016
2017 button_decal = gkrellm_create_decal_pixmap(p, decal_timer_button_pixmap,
2018 decal_timer_button_mask, N_TB_DECALS, style, -1, -1);
2019 button_decal->x = gkrellm_chart_width() - m->right - button_decal->w;
2020
2021 w_avail = button_decal->x - m->left - 3;
2022 if (bg_timer_piximage)
2023 w_avail -= tb->left + tb->right;
2024 w = gkrellm_gdk_string_width(ts->font, "0000:0000");
2025 sec_pad = gkrellm_gdk_string_width(ts->font, "0") * 2 / 3;
2026 if (w > w_avail)
2027 w = w_avail;
2028
2029 time_decal = gkrellm_create_decal_text(p, "0:", ts, style, -1, -1, w);
2030 seconds_decal = gkrellm_create_decal_text(p, "00",
2031 ts_alt, style, -1, -1, 0);
2032
2033 gkrellm_panel_configure(p, NULL, style);
2034
2035 /* Some special work needed here if there is a bg_timer. I have so
2036 | far the time_decal and button_decal fitting inside top/bottom margins.
2037 | If I add bg_timer borders to time_decal height and that ends up higher
2038 | than button_decal, I will need to grow the panel height.
2039 */
2040 h = time_decal->h;
2041 if (bg_timer_piximage)
2042 {
2043 gkrellm_get_top_bottom_margins(style, &top_margin, &bot_margin);
2044 h += tb->top + tb->bottom;
2045 time_decal->y += tb->top;
2046 time_decal->x += tb->left;
2047 if (h > button_decal->h) /* Need to grow the height ? */
2048 {
2049 gkrellm_panel_configure_set_height(p, h + top_margin + bot_margin);
2050 button_decal->y += (h - button_decal->h) / 2;
2051 }
2052 else /* button_decal->y is OK */
2053 time_decal->y += (button_decal->h - h) / 2;
2054 }
2055 else
2056 {
2057 /* time_decal and button_decal are initially at same y = top_margin
2058 */
2059 if (time_decal->h > button_decal->h)
2060 button_decal->y += (time_decal->h - button_decal->h) / 2;
2061 else
2062 time_decal->y += (button_decal->h - time_decal->h) / 2;
2063 }
2064
2065 seconds_decal->y = time_decal->y + time_decal->h - seconds_decal->h;
2066 gkrellm_panel_create(vbox, mon_timer, p);
2067
2068 gkrellm_move_decal(p, seconds_decal,
2069 time_decal->x + time_decal->w - seconds_decal->w,
2070 seconds_decal->y);
2071
2072 if (first_create)
2073 {
2074 g_signal_connect(G_OBJECT (p->drawing_area), "expose_event",
2075 G_CALLBACK(net_expose_event), NULL);
2076 g_signal_connect(G_OBJECT(p->drawing_area), "button_release_event",
2077 G_CALLBACK(cb_timer_button_release), NULL);
2078 g_signal_connect(G_OBJECT(p->drawing_area), "leave_notify_event",
2079 G_CALLBACK(cb_timer_button_release), NULL);
2080 g_signal_connect(G_OBJECT(p->drawing_area), "button_press_event",
2081 G_CALLBACK(cb_timer_button_press), NULL);
2082 }
2083
2084 if (bg_timer_piximage)
2085 {
2086 w += tb->left + tb->right;
2087 x = time_decal->x - tb->left;
2088 y = time_decal->y - tb->top;
2089 gkrellm_paste_piximage(bg_timer_piximage, p->pixmap, x, y, w, h);
2090 gkrellm_paste_piximage(bg_timer_piximage, p->bg_pixmap, x, y, w, h);
2091 gdk_draw_drawable(p->bg_text_layer_pixmap, _GK.draw1_GC, p->bg_pixmap,
2092 0, 0, 0, 0, p->w, p->h);
2093
2094 }
2095
2096 set_timer_button_state(timer_button_state);
2097 }
2098
2099 static void
update_net(void)2100 update_net(void)
2101 {
2102 GList *list;
2103 NetMon *net;
2104 struct tm *tm;
2105 GkrellmPanel *p;
2106 gint bytes;
2107 gdouble rxd, txd;
2108
2109 /* If sysdep code is not reporting route up/down events, then
2110 | gkrellm_net_assign_data() sets a net as up if data is assigned for it.
2111 | So, once a second, compare a net up state before a data read to the
2112 | state after a read and use that to internally generate up/down events.
2113 | If sysdep code assigns data even if a net is not routed, then there
2114 | will be no automatic chart toggling and charts will always be visible
2115 | if enabled.
2116 */
2117 if (GK.second_tick)
2118 {
2119 if (!net_use_routed)
2120 {
2121 for (list = net_mon_list; list; list = list->next)
2122 {
2123 net = (NetMon *) list->data;
2124 if (net->ignore)
2125 continue;
2126 net->up_prev = net->up;
2127 net->up = FALSE;
2128 }
2129 }
2130 else
2131 (*check_net_routes)();
2132 }
2133 (*read_net_data)();
2134 if (GK.second_tick && !net_use_routed)
2135 {
2136 for (list = net_mon_list; list; list = list->next)
2137 {
2138 net = (NetMon *) list->data;
2139 if (net->ignore)
2140 continue;
2141 if (net->up && !net->up_prev)
2142 net->up_event = TRUE;
2143 else if (!net->up && net->up_prev)
2144 net->down_event = TRUE;
2145 }
2146 }
2147 for (list = net_mon_list; list; list = list->next)
2148 {
2149 net = (NetMon *) list->data;
2150 if (!net->chart || net->ignore)
2151 continue;
2152 p = net->chart->panel;
2153 if (net->up || net->force_up)
2154 {
2155 if (net->rx > net->rx_old)
2156 draw_led(net, RX_LED, RX_ON);
2157 else
2158 draw_led(net, RX_LED, RX_OFF);
2159 if (net->tx > net->tx_old)
2160 draw_led(net, TX_LED, TX_ON);
2161 else
2162 draw_led(net, TX_LED, TX_OFF);
2163 }
2164 net->rx_old = net->rx;
2165 net->tx_old = net->tx;
2166 if (GK.second_tick)
2167 {
2168 gkrellm_store_chartdata(net->chart, 0, net->tx, net->rx);
2169 net->rx_current = gkrellm_get_current_chartdata(net->rx_cd);
2170 net->tx_current = gkrellm_get_current_chartdata(net->tx_cd);
2171 rxd = (gdouble) net->rx_current;
2172 txd = (gdouble) net->tx_current;
2173 net->rx_totalA += rxd;
2174 net->tx_totalA += txd;
2175 net->rx_totalB += rxd;
2176 net->tx_totalB += txd;
2177
2178 if (GK.day_tick)
2179 {
2180 tm = gkrellm_get_current_time();
2181 net_stats_shift_down(&net->day_stats[0], N_DAY_STATS,
2182 DAY_STAT);
2183
2184 if (tm->tm_wday == 0)
2185 net_stats_shift_down(&net->week_stats[0], N_WEEK_STATS,
2186 WEEK_STAT);
2187
2188 if (net_accounting_month_new(tm))
2189 net_stats_shift_down(&net->month_stats[0], N_MONTH_STATS,
2190 MONTH_STAT);
2191 }
2192 net->day_stats[0].rx += rxd;
2193 net->week_stats[0].rx += rxd;
2194 net->month_stats[0].rx += rxd;
2195
2196 net->day_stats[0].tx += txd;
2197 net->week_stats[0].tx += txd;
2198 net->month_stats[0].tx += txd;
2199
2200 if (net->alert)
2201 {
2202 bytes = 0;
2203 if (net->alert_uses_rx)
2204 bytes += net->rx_current;
2205 if (net->alert_uses_tx)
2206 bytes += net->tx_current;
2207 gkrellm_check_alert(net->alert, bytes);
2208 }
2209 gkrellm_panel_label_on_top_of_decals(p,
2210 gkrellm_alert_decal_visible(net->alert));
2211 refresh_net_chart(net);
2212 }
2213 gkrellm_update_krell(p, KRELL(p), net->tx + net->rx);
2214 gkrellm_draw_panel_layers(p);
2215 }
2216 if (GK.second_tick)
2217 {
2218 update_timer_button_monitor();
2219 timed_net_visibility();
2220 if (net_timed && !net_timed->up && !net_timed->force_up)
2221 {
2222 draw_led(net_timed, RX_LED, RX_OFF);
2223 draw_led(net_timed, TX_LED, TX_OFF);
2224 }
2225 for (list = net_mon_list; list; list = list->next)
2226 {
2227 net = (NetMon *) list->data;
2228 if (net->ignore)
2229 continue;
2230 if (!net->locked)
2231 {
2232 if (net->up_event && !net->chart && net->enabled)
2233 {
2234 create_net_monitor(dynamic_net_vbox, net, TRUE);
2235 gkrellm_pack_side_frames();
2236 }
2237 else if (net->down_event && net->chart)
2238 {
2239 destroy_chart(net);
2240 gkrellm_pack_side_frames();
2241 }
2242 }
2243 net->up_event = net->down_event = FALSE;
2244 }
2245 }
2246 if (GK.hour_tick)
2247 {
2248 tm = gkrellm_get_current_time();
2249 if ((tm->tm_hour % 6) == 0)
2250 gkrellm_net_save_data();
2251 }
2252 }
2253
2254 /* A timed interface has its chart locked and is forced enabled.
2255 */
2256 static void
create_timed_monitor(void)2257 create_timed_monitor(void)
2258 {
2259 GList *list;
2260 NetMon *net;
2261 TimerType *tt;
2262
2263 if (_GK.client_mode)
2264 return;
2265
2266 net_timed = NULL;
2267 timer_button_type = TIMER_TYPE_NONE;
2268 time(&net_timer0);
2269
2270 if (!*timer_button_iface || !strcmp(timer_button_iface, "none"))
2271 return;
2272
2273 /* Making a timed mon out of one that is already up? It needs to be
2274 | moved to a different vbox, so destroy and create dance.
2275 */
2276 for (list = net_mon_list; list; list = list->next)
2277 {
2278 net = (NetMon *) list->data;
2279 if (!strcmp(net->name, timer_button_iface))
2280 {
2281 destroy_chart(net);
2282 break;
2283 }
2284 }
2285 if ((net = lookup_net(timer_button_iface)) == NULL)
2286 net = new_net(timer_button_iface);
2287
2288 net->enabled = TRUE;
2289 net->locked = TRUE;
2290 create_net_monitor(net_vbox, net, TRUE);
2291 if (!net->up)
2292 gkrellm_chart_hide(net->chart, FALSE); /* Don't hide its panel */
2293
2294 net_timed = net;
2295 for (list = timer_defaults_list; list; list = list->next)
2296 {
2297 tt = (TimerType *) list->data;
2298 if (!strncmp(timer_button_iface, tt->name, strlen(tt->name) - 1))
2299 {
2300 timer_button_type = tt->type;
2301 break;
2302 }
2303 }
2304 get_connect_time();
2305 }
2306
2307
2308 static void
load_net_extra_piximages(void)2309 load_net_extra_piximages(void)
2310 {
2311 gchar **xpm;
2312 gint w, h;
2313
2314 /* Check for theme_dir/net/decal_net_leds.png.
2315 */
2316 gkrellm_load_piximage("decal_net_leds", decal_net_leds_xpm,
2317 &decal_net_led_piximage, NET_STYLE_NAME);
2318
2319 w = gdk_pixbuf_get_width(decal_net_led_piximage->pixbuf);
2320 w *= gkrellm_get_theme_scale();
2321
2322 h = gdk_pixbuf_get_height(decal_net_led_piximage->pixbuf) / N_LEDS;
2323 h *= gkrellm_get_theme_scale();
2324
2325 gkrellm_scale_piximage_to_pixmap(decal_net_led_piximage,
2326 &decal_net_led_pixmap, &decal_net_led_mask, w, h * N_LEDS);
2327
2328 /* Check for theme_dir/net/decal_timer_button.png
2329 */
2330 gkrellm_load_piximage("decal_timer_button", decal_timer_button_xpm,
2331 &decal_timer_button_piximage, TIMER_STYLE_NAME);
2332 h = gdk_pixbuf_get_height(decal_timer_button_piximage->pixbuf)
2333 / N_TB_DECALS;
2334 h *= gkrellm_get_theme_scale();
2335 gkrellm_scale_piximage_to_pixmap(decal_timer_button_piximage,
2336 &decal_timer_button_pixmap, &decal_timer_button_mask,
2337 -1, h * N_TB_DECALS);
2338
2339 /* Here is where I define the net timer panel theme extensions. I ask
2340 | for a theme extension image:
2341 | THEME_DIR/timer/bg_timer.png
2342 | and for a border for it from the gkrellmrc in the format:
2343 | set_piximage_border timer_bg_timer l,r,t,b
2344 | There is no default for bg_timer, ie it may end up being NULL.
2345 */
2346 if (!bg_timer_style) /* Used just for the bg_timer border */
2347 bg_timer_style = gkrellm_style_new0();
2348 if (bg_timer_piximage)
2349 gkrellm_destroy_piximage(bg_timer_piximage);
2350 bg_timer_piximage = NULL;
2351 xpm = (gkrellm_using_default_theme()) ? bg_timer_xpm : NULL;
2352 gkrellm_load_piximage("bg_timer", xpm,
2353 &bg_timer_piximage, TIMER_STYLE_NAME);
2354 gkrellm_set_gkrellmrc_piximage_border("timer_bg_timer",
2355 bg_timer_piximage, bg_timer_style);
2356 }
2357
2358 static void
net_spacer_visibility(void)2359 net_spacer_visibility(void)
2360 {
2361 GList *list;
2362 gboolean enabled = FALSE;
2363
2364 for (list = net_mon_list; list; list = list->next)
2365 if (((NetMon *) list->data)->enabled)
2366 enabled = TRUE;
2367 if (timer_button_enabled || enabled)
2368 gkrellm_spacers_show(mon_net);
2369 else
2370 gkrellm_spacers_hide(mon_net);
2371 }
2372
2373 static void
create_net(GtkWidget * vbox,gint first_create)2374 create_net(GtkWidget *vbox, gint first_create)
2375 {
2376 GList *list;
2377 NetMon *net;
2378
2379 load_net_extra_piximages();
2380
2381 /* Make a couple of vboxes here so I can control the net layout.
2382 | I want interface linked to the timer button to go last.
2383 */
2384 if (first_create)
2385 {
2386 dynamic_net_vbox = gtk_vbox_new(FALSE, 0);
2387 gtk_box_pack_start(GTK_BOX(vbox), dynamic_net_vbox, FALSE, FALSE, 0);
2388 gtk_widget_show(dynamic_net_vbox);
2389
2390 net_vbox = gtk_vbox_new(FALSE, 0);
2391 gtk_box_pack_start(GTK_BOX(vbox), net_vbox, FALSE, FALSE, 0);
2392 gtk_widget_show(net_vbox);
2393
2394 (*(read_net_data))(); /* need net up states */
2395
2396 create_timed_monitor();
2397 for (list = net_mon_list; list; list = list->next)
2398 {
2399 net = (NetMon *) list->data;
2400 if (net == net_timed)
2401 continue;
2402 if ((net->up || net->force_up) && net->enabled)
2403 create_net_monitor(dynamic_net_vbox, net, first_create);
2404 }
2405 load_net_data();
2406 }
2407 else
2408 {
2409 /* Some decals don't live in a panel, they will be drawn onto
2410 | charts when needed. So, must destroy them at create events (not
2411 | done automatically in panel lists) and then recreate them with NULL
2412 | panel and style pointers.
2413 */
2414 gkrellm_destroy_decal(decal_totalA);
2415 gkrellm_destroy_decal(decal_totalB);
2416 gkrellm_destroy_decal(decal_reset);
2417 gkrellm_destroy_decal(decal_stats);
2418 decal_totalA = decal_totalB = decal_reset = decal_stats = NULL;
2419 for (list = net_mon_list; list; list = list->next)
2420 {
2421 net = (NetMon *) list->data;
2422 if (net->chart)
2423 create_net_monitor(NULL, net, 0);
2424 }
2425 }
2426 decal_totalA = gkrellm_create_decal_pixmap(NULL,
2427 gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
2428 N_MISC_DECALS, NULL, 0, 0);
2429 decal_totalB = gkrellm_create_decal_pixmap(NULL,
2430 gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
2431 N_MISC_DECALS, NULL, 0, 0);
2432
2433 decal_reset = gkrellm_create_decal_pixmap(NULL,
2434 gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
2435 N_MISC_DECALS, NULL, 0, 0);
2436
2437 decal_stats = gkrellm_create_decal_pixmap(NULL,
2438 gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
2439 N_MISC_DECALS, NULL, 0, 0);
2440
2441 net_spacer_visibility();
2442 }
2443
2444 static void
create_timer(GtkWidget * vbox,gint first_create)2445 create_timer(GtkWidget *vbox, gint first_create)
2446 {
2447 timer_vbox = vbox;
2448 create_net_timer(timer_vbox, first_create);
2449 ascent = 0;
2450 ascent_alt = 0;
2451 if (first_create)
2452 draw_timer(timer_panel, (int) (time(0) - net_timer0), 1);
2453 else
2454 draw_timer(timer_panel, last_time , 1);
2455 gkrellm_draw_panel_layers(timer_panel);
2456 net_timer_visibility();
2457 }
2458
2459 #define NET_CONFIG_KEYWORD "net"
2460
2461 static void
cb_alert_trigger(GkrellmAlert * alert,NetMon * net)2462 cb_alert_trigger(GkrellmAlert *alert, NetMon *net)
2463 {
2464 /* Full panel alert, default decal.
2465 */
2466 alert->panel = net->chart->panel;
2467 }
2468
2469 static void
create_alert(NetMon * net)2470 create_alert(NetMon *net)
2471 {
2472 net->alert = gkrellm_alert_create(NULL, net->name,
2473 _("Bytes per second"),
2474 TRUE, FALSE, TRUE,
2475 1e10, 1000, 1000, 10000, 0);
2476 gkrellm_alert_delay_config(net->alert, 1, 60 * 60, 0);
2477
2478 gkrellm_alert_trigger_connect(net->alert, cb_alert_trigger, net);
2479 gkrellm_alert_config_connect(net->alert, cb_alert_config, net);
2480 gkrellm_alert_config_create_connect(net->alert,
2481 cb_alert_config_create, net);
2482 gkrellm_alert_command_process_connect(net->alert, cb_command_process, net);
2483 }
2484
2485
2486 static void
save_net_config(FILE * f)2487 save_net_config(FILE *f)
2488 {
2489 GList *list;
2490 NetMon *net;
2491
2492 for (list = net_mon_list; list; list = list->next)
2493 {
2494 net = (NetMon *) list->data;
2495 if ((!net->enabled && !net->real) || net->ignore)
2496 continue;
2497 fprintf(f, "%s enables %s %d %d %d\n", NET_CONFIG_KEYWORD, net->name,
2498 net->enabled, net->chart_labels, net->force_up);
2499 gkrellm_save_chartconfig(f, net->chart_config,
2500 NET_CONFIG_KEYWORD, net->name);
2501 if (*net->label)
2502 fprintf(f, "%s label %s %s\n", NET_CONFIG_KEYWORD,
2503 net->name, net->label);
2504 if (*(net->launch.command))
2505 fprintf(f, "%s launch %s %s\n", NET_CONFIG_KEYWORD,
2506 net->name, net->launch.command);
2507 if (*(net->launch.tooltip_comment))
2508 fprintf(f, "%s tooltip %s %s\n", NET_CONFIG_KEYWORD,
2509 net->name, net->launch.tooltip_comment);
2510 if (net->alert)
2511 {
2512 gkrellm_save_alertconfig(f, net->alert,
2513 NET_CONFIG_KEYWORD, net->name);
2514 fprintf(f, "%s extra_alert_config %s %d %d\n", NET_CONFIG_KEYWORD,
2515 net->name,
2516 net->alert_uses_rx, net->alert_uses_tx);
2517 }
2518 }
2519
2520 if (*net_ignore_patterns)
2521 fprintf(f, "%s ignore_patterns %s\n", NET_CONFIG_KEYWORD, net_ignore_patterns);
2522
2523 if (!_GK.client_mode || timer_button_type != TIMER_TYPE_SERVER)
2524 fprintf(f, "%s timer_enabled %d\n", NET_CONFIG_KEYWORD,
2525 timer_button_enabled);
2526 fprintf(f, "%s timer_seconds %d\n", NET_CONFIG_KEYWORD, timer_seconds);
2527 if (!_GK.client_mode)
2528 fprintf(f, "%s timer_iface %s\n", NET_CONFIG_KEYWORD,
2529 timer_button_iface);
2530 fprintf(f, "%s timer_on %s\n", NET_CONFIG_KEYWORD, timer_on_command);
2531 fprintf(f, "%s timer_off %s\n", NET_CONFIG_KEYWORD, timer_off_command);
2532 if (*text_format)
2533 fprintf(f, "%s text_format %s\n", NET_CONFIG_KEYWORD, text_format);
2534 fprintf(f, "%s reset_mday %d\n", NET_CONFIG_KEYWORD, reset_mday);
2535 fprintf(f, "%s net_enabled_as_default %d\n", NET_CONFIG_KEYWORD, net_enabled_as_default);
2536 fprintf(f, "%s net_stats_window_height %d\n", NET_CONFIG_KEYWORD,
2537 net_stats_window_height);
2538 }
2539
2540 static void
load_net_config(gchar * arg)2541 load_net_config(gchar *arg)
2542 {
2543 NetMon *net;
2544 gchar config[32], name[32];
2545 gchar item[CFG_BUFSIZE], item1[CFG_BUFSIZE];
2546 gboolean enable = TRUE, ch_labels = TRUE, force = FALSE;
2547 gint n;
2548
2549 n = sscanf(arg, "%31s %[^\n]", config, item);
2550 if (n != 2)
2551 return;
2552
2553 if (!_GK.client_mode || timer_button_type != TIMER_TYPE_SERVER)
2554 if (!strcmp(config, "timer_enabled") && ! _GK.demo)
2555 sscanf(item, "%d", &timer_button_enabled);
2556
2557 if (!strcmp(config, "timer_seconds"))
2558 sscanf(item, "%d", &timer_seconds);
2559 else if (!strcmp(config, "reset_mday"))
2560 sscanf(item, "%d", &reset_mday);
2561 else if (!strcmp(config, "net_enabled_as_default"))
2562 sscanf(item, "%d", &net_enabled_as_default);
2563 else if (!strcmp(config, "net_stats_window_height"))
2564 sscanf(item, "%d", &net_stats_window_height);
2565 else if (!strcmp(config, "timer_iface") && !_GK.client_mode)
2566 {
2567 if (_GK.demo && !strcmp(item, "none"))
2568 gkrellm_dup_string(&timer_button_iface, "ppp0");
2569 else
2570 gkrellm_dup_string(&timer_button_iface, item);
2571 }
2572 else if (!strcmp(config, "timer_on"))
2573 gkrellm_dup_string(&timer_on_command, item);
2574 else if (!strcmp(config, "timer_off"))
2575 gkrellm_dup_string(&timer_off_command, item);
2576 else if (!strcmp(config, "text_format"))
2577 gkrellm_locale_dup_string(&text_format, item, &text_format_locale);
2578 else if (!strcmp(config, "ignore_patterns"))
2579 gkrellm_dup_string(&net_ignore_patterns, item);
2580 else if (sscanf(item, "%31s %[^\n]", name, item1) == 2)
2581 {
2582 if (!strcmp(config, "iface")) /* Hack to get some of 1.0 config */
2583 { /* Can't get resolution, label, launch or tooltip */
2584 sscanf(item1, "%*d %d %*s %d %d", &enable, &ch_labels, &force);
2585 strcpy(config, "enables");
2586 snprintf(item1, sizeof(item1), "%d %d %d", enable, ch_labels, force);
2587 }
2588 /* Remaining configs will have a net name
2589 */
2590 if (!strcmp(config, "enables"))
2591 {
2592 if ((net = lookup_net(name)) == NULL)
2593 net = new_net(name);
2594 if (net && !net->ignore)
2595 {
2596 sscanf(item1, "%d %d %d", &net->enabled, &net->chart_labels,
2597 &net->force_up);
2598 if (!net_use_routed)
2599 net->force_up = FALSE;
2600 }
2601 return;
2602 }
2603 if ((net = lookup_net(name)) == NULL || net->ignore)
2604 return;
2605 if (!strcmp(config, GKRELLM_CHARTCONFIG_KEYWORD))
2606 gkrellm_load_chartconfig(&net->chart_config, item1, 2);
2607 else if (!strcmp(config, GKRELLM_ALERTCONFIG_KEYWORD))
2608 {
2609 if (!net->alert)
2610 create_alert(net);
2611 gkrellm_load_alertconfig(&net->alert, item1);
2612 }
2613 else if (!strcmp(config, "extra_alert_config"))
2614 sscanf(item1, "%d %d", &net->alert_uses_rx, &net->alert_uses_tx);
2615 else if (!strcmp(config, "label"))
2616 gkrellm_dup_string(&net->label, item1);
2617 else if (!strcmp(config, "launch"))
2618 gkrellm_dup_string(&net->launch.command, item1);
2619 else if (!strcmp(config, "tooltip"))
2620 gkrellm_dup_string(&net->launch.tooltip_comment, item1);
2621 }
2622 }
2623
2624
2625 /* -------------- User config interface --------------------- */
2626
2627 #define STEP 1
2628
2629 static GtkWidget *pon_entry,
2630 *poff_entry,
2631 *net_ignore_entry,
2632 *timer_iface_combo_box,
2633 *text_format_combo_box;
2634
2635 static GtkWidget *enable_net_timer_button;
2636 static GtkWidget *net_timer_seconds_button;
2637
2638 static gboolean enable_in_progress;
2639
2640
2641 static void
sync_chart(NetMon * net)2642 sync_chart(NetMon *net)
2643 {
2644 /* If enabling, fake an up_event so update_net() will create the chart.
2645 */
2646 if (net->enabled && !net->chart && (net->up || net->force_up))
2647 net->up_event = TRUE;
2648 else if ( net->chart
2649 && (!net->enabled || (!net->locked && !net->force_up && !net->up))
2650 )
2651 destroy_chart(net);
2652 }
2653
2654 static void
cb_force(GtkWidget * button,NetMon * net)2655 cb_force(GtkWidget *button, NetMon *net)
2656 {
2657 if (enable_in_progress)
2658 return;
2659 net->force_up = GTK_TOGGLE_BUTTON(button)->active;
2660 if (net != net_timed)
2661 net->locked = FALSE;
2662 sync_chart(net);
2663 }
2664
2665 static void
cb_enable(GtkWidget * button,NetMon * net)2666 cb_enable(GtkWidget *button, NetMon *net)
2667 {
2668 enable_in_progress = TRUE;
2669 net->enabled = GTK_TOGGLE_BUTTON(button)->active;
2670 if (net->force_button)
2671 {
2672 if (net->enabled)
2673 gtk_widget_set_sensitive(net->force_button, TRUE);
2674 else
2675 {
2676 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(net->force_button),
2677 FALSE);
2678 gtk_widget_set_sensitive(net->force_button, FALSE);
2679 net->force_up = FALSE;
2680 }
2681 }
2682 gtk_widget_set_sensitive(net->alert_button, net->enabled);
2683 if (net == net_timed && !net->enabled && timer_iface_combo_box)
2684 gtk_combo_box_set_active(GTK_COMBO_BOX(timer_iface_combo_box), 0);
2685 else
2686 sync_chart(net);
2687 enable_in_progress = FALSE;
2688 net_spacer_visibility();
2689 }
2690
2691 static void
cb_launch_entry(GtkWidget * widget,NetMon * net)2692 cb_launch_entry(GtkWidget *widget, NetMon *net)
2693 {
2694 if (net->chart)
2695 gkrellm_apply_launcher(&net->launch_entry, &net->tooltip_entry,
2696 net->chart->panel, &net->launch, gkrellm_launch_button_cb);
2697 }
2698
2699 static void
cb_text_format(GtkWidget * widget,gpointer data)2700 cb_text_format(GtkWidget *widget, gpointer data)
2701 {
2702 GList *list;
2703 NetMon *net;
2704 gchar *s;
2705 GtkWidget *entry;
2706
2707 entry = gtk_bin_get_child(GTK_BIN(text_format_combo_box));
2708 s = gkrellm_gtk_entry_get_text(&entry);
2709 gkrellm_locale_dup_string(&text_format, s, &text_format_locale);
2710 for (list = net_mon_list; list; list = list->next)
2711 {
2712 net = (NetMon *) list->data;
2713 net->new_text_format = TRUE;
2714 refresh_net_chart(net);
2715 }
2716 }
2717
2718 static void
cb_label_entry(GtkWidget * widget,NetMon * net)2719 cb_label_entry(GtkWidget *widget, NetMon *net)
2720 {
2721 gkrellm_dup_string(&net->label,
2722 gkrellm_gtk_entry_get_text(&net->label_entry));
2723 refresh_net_chart(net);
2724 }
2725
2726 static void
cb_set_alert(GtkWidget * button,NetMon * net)2727 cb_set_alert(GtkWidget *button, NetMon *net)
2728 {
2729
2730 #if 0
2731 GtkTreeModel *model;
2732 GtkTreePath *path;
2733 GtkTreeIter iter;
2734 NetMon *net;
2735
2736 if (!row_reference)
2737 return;
2738 model = gtk_tree_view_get_model(treeview);
2739 path = gtk_tree_row_reference_get_path(row_reference);
2740 gtk_tree_model_get_iter(model, &iter, path);
2741 gtk_tree_model_get(model, &iter, NETMON_COLUMN, &net, -1);
2742 #endif
2743
2744 if (!net->alert)
2745 create_alert(net);
2746 gkrellm_alert_config_window(&net->alert);
2747
2748 #if 0
2749 gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
2750 ALERT_COLUMN, net->alert, -1);
2751 #endif
2752 }
2753
2754 /* Callback for a created or destroyed alert. Find the sensor in the model
2755 | and set the IMAGE_COLUMN.
2756 */
2757 static void
cb_alert_config(GkrellmAlert * ap,NetMon * net)2758 cb_alert_config(GkrellmAlert *ap, NetMon *net)
2759 {
2760 #if 0
2761 GtkTreeModel *model;
2762 GtkTreeIter iter;
2763 NetMon *net_test;
2764 GdkPixbuf *pixbuf;
2765 gchar node[2];
2766 gint i;
2767
2768 if (!gkrellm_config_window_shown())
2769 return;
2770 model = gtk_tree_view_get_model(treeview);
2771 pixbuf = ap->activated ? gkrellm_alert_pixbuf() : NULL;
2772 for (i = 0; i < 2; ++i)
2773 {
2774 node[0] = '0' + i; /* toplevel Primary or Secondary node */
2775 node[1] = '\0';
2776 if (get_child_iter(model, node, &iter))
2777 do
2778 {
2779 gtk_tree_model_get(model, &iter, NETMON_COLUMN, &net_test, -1);
2780 if (net != net_test)
2781 continue;
2782 gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
2783 IMAGE_COLUMN, pixbuf, -1);
2784 return;
2785 }
2786 while (gtk_tree_model_iter_next(model, &iter));
2787 }
2788 #endif
2789 net->alert_uses_rx =
2790 GTK_TOGGLE_BUTTON(net->alert_config_rx_button)->active;
2791 net->alert_uses_tx =
2792 GTK_TOGGLE_BUTTON(net->alert_config_tx_button)->active;
2793 }
2794
2795 static void
cb_alert_config_button(GtkWidget * button,NetMon * net)2796 cb_alert_config_button(GtkWidget *button, NetMon *net)
2797 {
2798 gboolean read, write;
2799
2800 read = GTK_TOGGLE_BUTTON(net->alert_config_rx_button)->active;
2801 write = GTK_TOGGLE_BUTTON(net->alert_config_tx_button)->active;
2802 if (!read && !write)
2803 {
2804 gtk_toggle_button_set_active(
2805 GTK_TOGGLE_BUTTON(net->alert_config_rx_button), TRUE);
2806 gtk_toggle_button_set_active(
2807 GTK_TOGGLE_BUTTON(net->alert_config_tx_button), TRUE);
2808 }
2809 }
2810
2811 static void
cb_alert_config_create(GkrellmAlert * ap,GtkWidget * vbox,NetMon * net)2812 cb_alert_config_create(GkrellmAlert *ap, GtkWidget *vbox, NetMon *net)
2813 {
2814 gkrellm_gtk_check_button_connected(vbox, &net->alert_config_rx_button,
2815 net->alert_uses_rx, FALSE, FALSE, 2,
2816 cb_alert_config_button, net, _("rx bytes"));
2817 gkrellm_gtk_check_button_connected(vbox, &net->alert_config_tx_button,
2818 net->alert_uses_tx, FALSE, FALSE, 2,
2819 cb_alert_config_button, net, _("tx bytes"));
2820 }
2821
2822
2823 static void
cb_timer_enable(GtkWidget * button,gpointer data)2824 cb_timer_enable(GtkWidget *button, gpointer data)
2825 {
2826 gkrellm_panel_enable_visibility(timer_panel,
2827 GTK_TOGGLE_BUTTON(enable_net_timer_button)->active,
2828 &timer_button_enabled);
2829 gtk_widget_set_sensitive(net_timer_seconds_button, timer_button_enabled);
2830 if (timer_iface_combo_box)
2831 {
2832 /* Reset to "none" combo box entry */
2833 if (!timer_button_enabled)
2834 gtk_combo_box_set_active(GTK_COMBO_BOX(timer_iface_combo_box), 0);
2835 gtk_widget_set_sensitive(timer_iface_combo_box, timer_button_enabled);
2836 }
2837 net_timer_visibility();
2838 }
2839
2840 static void
cb_timer_seconds(GtkWidget * button,gpointer data)2841 cb_timer_seconds(GtkWidget *button, gpointer data)
2842 {
2843 timer_seconds = GTK_TOGGLE_BUTTON(button)->active;
2844 gkrellm_panel_destroy(timer_panel);
2845 create_net_timer(timer_vbox, TRUE);
2846 draw_timer(timer_panel, last_time , 1);
2847 }
2848
2849 static void
cb_timer_iface(GtkWidget * widget,gpointer data)2850 cb_timer_iface(GtkWidget *widget, gpointer data)
2851 {
2852 gchar *s;
2853 GtkWidget *entry;
2854
2855 entry = gtk_bin_get_child(GTK_BIN(timer_iface_combo_box));
2856 s = gkrellm_gtk_entry_get_text(&entry);
2857 if (*s == '\0' || strcmp(s, _("none")) == 0 || net_ignore_match(s))
2858 s = "none";
2859 if (gkrellm_dup_string(&timer_button_iface, s))
2860 {
2861 /* A new timer_button_iface, so destroy old one. If the old one
2862 | is up or forced up, a new chart for it needs to be created in
2863 | another vbox, so fake an up_event.
2864 */
2865 if (net_timed)
2866 {
2867 destroy_chart(net_timed);
2868 if ( net_timed->enabled
2869 && (net_timed->up || net_timed->force_up)
2870 )
2871 net_timed->up_event = TRUE;
2872 }
2873 create_timed_monitor();
2874 if (net_timed)
2875 gtk_toggle_button_set_active(
2876 GTK_TOGGLE_BUTTON(net_timed->enable_button), TRUE);
2877 draw_timer(timer_panel, (int) (time(0) - net_timer0), 1);
2878 gkrellm_draw_panel_layers(timer_panel);
2879 }
2880 }
2881
2882 static void
cb_pon_entry(GtkWidget * widget,gpointer data)2883 cb_pon_entry(GtkWidget *widget, gpointer data)
2884 {
2885 gchar *s;
2886
2887 s = gkrellm_gtk_entry_get_text(&pon_entry);
2888 gkrellm_dup_string(&timer_on_command, s);
2889 }
2890
2891 static void
cb_poff_entry(GtkWidget * widget,gpointer data)2892 cb_poff_entry(GtkWidget *widget, gpointer data)
2893 {
2894 gchar *s;
2895
2896 s = gkrellm_gtk_entry_get_text(&poff_entry);
2897 gkrellm_dup_string(&timer_off_command, s);
2898 }
2899
2900 static void
cb_reset_mday(GtkWidget * widget,GtkSpinButton * spin)2901 cb_reset_mday(GtkWidget *widget, GtkSpinButton *spin)
2902 {
2903 GList *list;
2904 NetMon *net;
2905 NetStat *ns;
2906 struct tm *tm;
2907 gint year, month, mday, month_delta;
2908
2909 reset_mday = gtk_spin_button_get_value_as_int(spin);
2910
2911 for (list = net_mon_list; list; list = list->next)
2912 {
2913 net = (NetMon *) list->data;
2914 net->month_stats[0].rx = net->month_stats[0].tx = 0.0;
2915 net->month_stats[0].connect_time = 0;
2916 tm = gkrellm_get_current_time();
2917 net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, tm);
2918
2919 for (ns = &net->day_stats[0]; ns < &net->day_stats[N_DAY_STATS]; ++ns)
2920 {
2921 if (sscanf(ns->date, "%d-%d-%d", &year, &month, &mday) != 3)
2922 continue;
2923 year -= 1900; /* Adjust to struct tm ranges */
2924 month -= 1;
2925 month_delta = (tm->tm_year * 12 + tm->tm_mon)
2926 - (year * 12 + month);
2927 if ( ( tm->tm_mday < reset_mday
2928 && ( (month_delta > 1)
2929 || (month_delta == 1 && mday < reset_mday)
2930 )
2931 )
2932 || ( tm->tm_mday >= reset_mday
2933 && ( (month_delta > 0)
2934 || (month_delta == 0 && mday < reset_mday)
2935 )
2936 )
2937 )
2938 continue;
2939
2940 net->month_stats[0].rx += ns->rx;
2941 net->month_stats[0].tx += ns->tx;
2942 net->month_stats[0].connect_time += ns->connect_time;
2943 }
2944 }
2945 }
2946
2947 static void
cb_net_enabled_as_default(GtkWidget * button,gpointer data)2948 cb_net_enabled_as_default(GtkWidget *button, gpointer data)
2949 {
2950 net_enabled_as_default = GTK_TOGGLE_BUTTON(button)->active;
2951 }
2952
2953 static void
net_ignore_entry_cb(GtkWidget * widget,gpointer data)2954 net_ignore_entry_cb(GtkWidget *widget, gpointer data)
2955 {
2956 NetMon *net;
2957 GList *list;
2958 gchar *str = gkrellm_gtk_entry_get_text(&net_ignore_entry);
2959 gboolean prev_ignore;
2960
2961 gkrellm_dup_string(&net_ignore_patterns, str);
2962 for (list = net_mon_list; list; list = list->next)
2963 {
2964 net = (NetMon *) list->data;
2965 prev_ignore = net->ignore;
2966 net->ignore = net_ignore_match(net->name);
2967 if (net->ignore && !prev_ignore)
2968 {
2969 net->enabled = FALSE;
2970 sync_chart(net);
2971 net_spacer_visibility();
2972 }
2973 else if (!net->ignore && prev_ignore)
2974 {
2975 net->enabled = net_enabled_as_default;
2976 sync_chart(net);
2977 net_spacer_visibility();
2978 }
2979 if (net->force_button)
2980 {
2981 if (net->enabled)
2982 gtk_widget_set_sensitive(net->force_button, TRUE);
2983 else
2984 {
2985 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(net->force_button),
2986 FALSE);
2987 gtk_widget_set_sensitive(net->force_button, FALSE);
2988 net->force_up = FALSE;
2989 }
2990 }
2991 if (net->alert_button)
2992 gtk_widget_set_sensitive(net->alert_button, net->enabled);
2993 if (net == net_timed && !net->enabled && timer_iface_combo_box)
2994 gtk_combo_box_set_active(GTK_COMBO_BOX(timer_iface_combo_box), 0);
2995 }
2996 }
2997
2998 #if !defined(WIN32)
2999 static gchar *net_info_text0[] =
3000 {
3001 N_("<h>Timer Button\n"),
3002 N_("\tThe timer button may be used as a stand alone timer with start and\n"
3003 "\tstop commands, but it is usually linked to a dial up net interface\n"
3004 "\twhere the commands can control the interface and different timer\n"
3005 "\tbutton colors can show connect states:\n"),
3006 "\n",
3007 #if defined(__FreeBSD__)
3008 "<b>\ttun: ",
3009 #else
3010 "<b>\tppp: ",
3011 #endif
3012 N_("Standby state is while the modem phone line is locked while\n"
3013 "\tppp is connecting, and the on state is the ppp link connected.\n"
3014 "\tThe phone line lock is determined by the existence of the modem\n"
3015 "\tlock file /var/lock/LCK..modem. If your pppd setup does not\n"
3016 "\tuse /dev/modem, then you can configure an alternative with:\n"),
3017 N_("<i>\t\tln -s /var/lock/LCK..ttySx ~/.gkrellm2/LCK..modem\n"),
3018 N_("\twhere ttySx is the tty device your modem uses. The ppp on\n"
3019 "\tstate is detected by the existence of /var/run/pppX.pid and\n"
3020 "\tthe time stamp of this file is the base for the on line time.\n"),
3021 #if defined(__linux__)
3022 "\n",
3023 "<b>\tippp: ",
3024 N_("The timer button standby state is not applicable to isdn\n"
3025 "\tinterfaces that are always routed. The on state is isdn on line\n"
3026 "\twhile the ippp interface is routed. The on line timer is reset\n"
3027 "\twhen the isdn interface transitions from a hangup to an on line\n"
3028 "\tstate\n"),
3029 #endif
3030 "\n"
3031 };
3032 #endif
3033
3034 static gchar *net_info_text1[] =
3035 {
3036 N_("<h>Chart Labels\n"),
3037 N_("Substitution variables for the format string for chart labels:\n"),
3038 N_("\t$M maximum chart value\n"),
3039 N_("\t$T receive + transmit bytes\n"),
3040 N_("\t$r receive bytes\n"),
3041 N_("\t$t transmit bytes\n"),
3042 N_("\t$O cumulative receive + transmit bytes\n"),
3043 N_("\t$i cumulative receive bytes\n"),
3044 N_("\t$o cumulative transmit bytes\n"),
3045 N_("\t$L the optional chart label\n"),
3046 N_("\t$I the net interface name\n"),
3047 "\n",
3048 N_("The cumulative variables may have a 'd', 'w', or 'm' qualifier for\n"
3049 "daily, weekly, or monthly totals. For example: $Ow for a\n"
3050 "cumulative weekly receive + transmit bytes.\n"),
3051 "\n",
3052 N_("Substitution variables may be used in alert commands.\n")
3053 };
3054
3055 static void
create_net_tab(GtkWidget * tab_vbox)3056 create_net_tab(GtkWidget *tab_vbox)
3057 {
3058 GtkWidget *tabs;
3059 GtkWidget *table;
3060 GtkWidget *vbox, *vbox1;
3061 GtkWidget *hbox;
3062 GtkWidget *label;
3063 GtkWidget *text;
3064 GList *list, *tlist;
3065 NetMon *net;
3066 TimerType *tt;
3067 gchar buf[256];
3068 gint i;
3069
3070 tabs = gtk_notebook_new();
3071 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
3072 gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
3073
3074 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Timer Button"));
3075
3076 if (timer_button_type != TIMER_TYPE_SERVER) /* enabled by gkrellmd.conf? */
3077 gkrellm_gtk_check_button_connected(vbox, &enable_net_timer_button,
3078 timer_button_enabled, FALSE, FALSE, 10,
3079 cb_timer_enable, NULL,
3080 _("Enable timer button"));
3081
3082 gkrellm_gtk_check_button_connected(vbox, &net_timer_seconds_button,
3083 timer_seconds, FALSE, FALSE, 0,
3084 cb_timer_seconds, NULL,
3085 _("Show seconds"));
3086 gtk_widget_set_sensitive(net_timer_seconds_button, timer_button_enabled);
3087 hbox = gtk_hbox_new (FALSE, 3);
3088 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
3089 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 50);
3090
3091 if (!_GK.client_mode)
3092 {
3093 timer_iface_combo_box = gtk_combo_box_entry_new_text();
3094 gtk_box_pack_start(GTK_BOX(hbox), timer_iface_combo_box, TRUE, TRUE, 0);
3095 gtk_widget_set_sensitive(timer_iface_combo_box, timer_button_enabled);
3096 gtk_combo_box_append_text(GTK_COMBO_BOX(timer_iface_combo_box),
3097 _("none"));
3098 for (tlist = timer_defaults_list; tlist; tlist = tlist->next)
3099 {
3100 tt = (TimerType *) tlist->data;
3101 gtk_combo_box_append_text(GTK_COMBO_BOX(timer_iface_combo_box),
3102 tt->name);
3103 }
3104 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(
3105 GTK_BIN(timer_iface_combo_box))), timer_button_iface);
3106 g_signal_connect(G_OBJECT(timer_iface_combo_box), "changed",
3107 G_CALLBACK(cb_timer_iface), NULL);
3108
3109 label = gtk_label_new(_("Interface to link to the timer button"));
3110 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
3111 }
3112 vbox = gkrellm_gtk_framed_vbox_end(vbox, NULL, 4, FALSE, 0, 2);
3113 hbox = gtk_hbox_new (FALSE, 3);
3114 gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
3115 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3116
3117 vbox1 = gtk_vbox_new(FALSE, 3);
3118 gtk_container_set_border_width(GTK_CONTAINER(vbox1), 3);
3119 gtk_container_add(GTK_CONTAINER(hbox), vbox1);
3120 label = gtk_label_new(_("Start Command"));
3121 gtk_box_pack_start(GTK_BOX (vbox1), label, FALSE, TRUE, 0);
3122 pon_entry = gtk_entry_new();
3123 gtk_box_pack_start(GTK_BOX (vbox1), pon_entry, FALSE, TRUE, 0);
3124 gtk_entry_set_text(GTK_ENTRY(pon_entry), timer_on_command);
3125 g_signal_connect(G_OBJECT(pon_entry),
3126 "changed", G_CALLBACK(cb_pon_entry), NULL);
3127
3128 vbox1 = gtk_vbox_new(FALSE, 3);
3129 gtk_container_set_border_width(GTK_CONTAINER(vbox1), 3);
3130 gtk_container_add(GTK_CONTAINER(hbox), vbox1);
3131 label = gtk_label_new(_("Stop Command"));
3132 gtk_box_pack_start(GTK_BOX (vbox1), label, FALSE, TRUE, 0);
3133 poff_entry = gtk_entry_new();
3134 gtk_box_pack_start(GTK_BOX (vbox1), poff_entry, FALSE, TRUE, 0);
3135 gtk_entry_set_text(GTK_ENTRY(poff_entry), timer_off_command);
3136 g_signal_connect(G_OBJECT(poff_entry),
3137 "changed", G_CALLBACK(cb_poff_entry), NULL);
3138
3139 for (list = net_mon_list; list; list = list->next)
3140 {
3141 net = (NetMon *) list->data;
3142 if (net->ignore)
3143 {
3144 net->alert_button = NULL;
3145 net->force_button = NULL;
3146 continue;
3147 }
3148 vbox = gkrellm_gtk_framed_notebook_page(tabs, net->name);
3149
3150 snprintf(buf, sizeof(buf), _("Enable %s"), net->name);
3151 hbox = gtk_hbox_new (FALSE, 0);
3152 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
3153 gkrellm_gtk_check_button_connected(hbox,
3154 &net->enable_button, net->enabled,
3155 FALSE, FALSE, 0,
3156 cb_enable, net, buf);
3157 gkrellm_gtk_alert_button(hbox, &net->alert_button, FALSE, FALSE, 4,
3158 FALSE, cb_set_alert, net);
3159 gtk_widget_set_sensitive(net->alert_button, net->enabled);
3160
3161
3162 if (net_config_use_routed)
3163 {
3164 gkrellm_gtk_check_button_connected(vbox, &net->force_button,
3165 net->enabled ? net->force_up : FALSE, FALSE, FALSE, 0,
3166 cb_force, net,
3167 _("Force chart to be always shown even if interface is not routed."));
3168 if (!net->enabled)
3169 gtk_widget_set_sensitive(net->force_button, FALSE);
3170 }
3171
3172 hbox = gtk_hbox_new (FALSE, 0);
3173 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 12);
3174
3175 net->label_entry = gtk_entry_new();
3176 gtk_entry_set_max_length(GTK_ENTRY(net->label_entry), 16);
3177 gtk_widget_set_size_request(net->label_entry, 70, -1);
3178 gtk_entry_set_text(GTK_ENTRY(net->label_entry), net->label);
3179 gtk_box_pack_start (GTK_BOX (hbox), net->label_entry, FALSE, TRUE, 2);
3180 label = gtk_label_new(_("Optional label for this interface."));
3181 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
3182 g_signal_connect(G_OBJECT(net->label_entry), "changed",
3183 G_CALLBACK(cb_label_entry), net);
3184
3185 vbox = gkrellm_gtk_category_vbox(vbox,
3186 _("Launch Commands"),
3187 4, 0, TRUE);
3188 table = gkrellm_gtk_launcher_table_new(vbox, 1);
3189 gkrellm_gtk_config_launcher(table, 0, &net->launch_entry,
3190 &net->tooltip_entry, net->name, &net->launch);
3191 g_signal_connect(G_OBJECT(net->launch_entry), "changed",
3192 G_CALLBACK(cb_launch_entry), net);
3193 g_signal_connect(G_OBJECT(net->tooltip_entry), "changed",
3194 G_CALLBACK(cb_launch_entry), net);
3195 }
3196
3197 /* -- Setup tab */
3198 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Setup"));
3199
3200 vbox1 = gkrellm_gtk_category_vbox(vbox,
3201 _("Format String for Chart Labels"),
3202 4, 0, TRUE);
3203 text_format_combo_box = gtk_combo_box_entry_new_text();
3204 gtk_widget_set_size_request (GTK_WIDGET(text_format_combo_box), 300, -1);
3205 gtk_box_pack_start(GTK_BOX(vbox1), text_format_combo_box, FALSE, FALSE, 2);
3206 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box), text_format);
3207 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box),
3208 DEFAULT_TEXT_FORMAT);
3209 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box),
3210 "\\c\\f$M\\n$T\\b\\c\\f$L");
3211 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box),
3212 _("\\f\\ww\\c\\f$M\\n\\f\\at\\.$t\\n\\f\\ar\\.$r\\b\\c\\f$L"));
3213 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box),
3214 _("\\f\\ww\\c\\f$M\\n\\f\\at\\.$o\\n\\f\\ar\\.$i\\b\\c\\f$L"));
3215 gtk_combo_box_append_text(GTK_COMBO_BOX(text_format_combo_box),
3216 _("\\f\\ww\\c\\f$M\\D2\\f\\ar\\.$r\\D1\\f\\at\\.$t\\b\\c\\f$L"));
3217 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(text_format_combo_box))),
3218 text_format);
3219 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(text_format_combo_box)), "changed",
3220 G_CALLBACK(cb_text_format), NULL);
3221
3222 vbox1 = gkrellm_gtk_category_vbox(vbox,
3223 _("Ignore Net Interfaces"),
3224 4, 0, TRUE);
3225 label = gtk_label_new(_("Space separated list of patterns.\n"));
3226 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
3227 hbox = gtk_hbox_new(FALSE, 0);
3228 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
3229 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
3230
3231 hbox = gtk_hbox_new(FALSE, 0);
3232 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
3233 net_ignore_entry = gtk_entry_new();
3234 snprintf(buf, sizeof(buf), "%s", net_ignore_patterns);
3235 gtk_entry_set_text(GTK_ENTRY(net_ignore_entry), buf);
3236 gtk_box_pack_start(GTK_BOX(hbox), net_ignore_entry, FALSE, FALSE, 0);
3237 g_signal_connect(G_OBJECT(net_ignore_entry), "changed",
3238 G_CALLBACK(net_ignore_entry_cb), NULL);
3239
3240 gkrellm_gtk_spin_button(vbox, NULL, (gfloat) reset_mday,
3241 1.0, 31.0, 1.0, 1.0, 0, 55,
3242 cb_reset_mday, NULL, FALSE,
3243 _("Start day for cumulative monthly transmit and receive bytes"));
3244
3245 gkrellm_gtk_check_button_connected(vbox, &net_enabled_as_default_button,
3246 net_enabled_as_default, FALSE, FALSE, 10,
3247 cb_net_enabled_as_default, NULL,
3248 _("Enable new interfaces"));
3249
3250 /* --Info tab */
3251 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Info"));
3252 text = gkrellm_gtk_scrolled_text_view(vbox, NULL,
3253 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3254 #if !defined(WIN32)
3255 if (!_GK.client_mode)
3256 for (i = 0; i < sizeof(net_info_text0)/sizeof(gchar *); ++i)
3257 gkrellm_gtk_text_view_append(text, _(net_info_text0[i]));
3258 #endif
3259 for (i = 0; i < sizeof(net_info_text1)/sizeof(gchar *); ++i)
3260 gkrellm_gtk_text_view_append(text, _(net_info_text1[i]));
3261 }
3262
3263
3264
3265 static GkrellmMonitor monitor_net =
3266 {
3267 N_("Net"), /* Name, for config tab. */
3268 MON_NET, /* Id, 0 if a plugin */
3269 create_net, /* The create function */
3270 update_net, /* The update function */
3271 create_net_tab, /* The config tab create function */
3272 NULL, /* Instant apply */
3273
3274 save_net_config, /* Save user conifg */
3275 load_net_config, /* Load user config */
3276 NET_CONFIG_KEYWORD, /* config keyword */
3277
3278 NULL, /* Undef 2 */
3279 NULL, /* Undef 1 */
3280 NULL, /* Undef 0 */
3281
3282 0, /* insert_before_id - place plugin before this mon */
3283
3284 NULL, /* Handle if a plugin, filled in by GKrellM */
3285 NULL /* path if a plugin, filled in by GKrellM */
3286 };
3287
3288 GkrellmMonitor *
gkrellm_init_net_monitor(void)3289 gkrellm_init_net_monitor(void)
3290 {
3291 TimerType *tt;
3292
3293 if (!setup_net_interface())
3294 return NULL;
3295 time(&net_timer0);
3296 if (timer_defaults_list)
3297 {
3298 tt = (TimerType *) timer_defaults_list->data;
3299 timer_button_iface = g_strdup(tt->name);
3300 timer_button_type = tt->type;
3301 }
3302 else
3303 {
3304 timer_button_iface = g_strdup("none");
3305 }
3306 if (!_GK.client_mode)
3307 timer_button_enabled = TRUE;
3308 else
3309 timer_button_enabled = (timer_button_type == TIMER_TYPE_SERVER);
3310
3311 timer_seconds = TRUE;
3312 timer_on_command = g_strdup("");
3313 timer_off_command = g_strdup("");
3314
3315 net_enabled_as_default = TRUE;
3316
3317 gkrellm_locale_dup_string(&text_format, DEFAULT_TEXT_FORMAT,
3318 &text_format_locale);
3319 gkrellm_dup_string(&net_ignore_patterns, "");
3320
3321 net_stats_window_height = 200;
3322
3323 monitor_net.name = _(monitor_net.name);
3324 net_style_id = gkrellm_add_chart_style(&monitor_net, NET_STYLE_NAME);
3325 mon_net = &monitor_net;
3326 return &monitor_net;
3327 }
3328
3329
3330 static GkrellmMonitor monitor_timer =
3331 {
3332 N_("Net Timer"), /* Name, for config tab. */
3333 MON_TIMER, /* Id, 0 if a plugin */
3334 create_timer, /* The create function */
3335 NULL, /* The update function */
3336 NULL, /* The config tab create function */
3337 NULL, /* Apply the config function */
3338
3339 NULL, /* Save user conifg */
3340 NULL, /* Load user config */
3341 NULL, /* config keyword */
3342
3343 NULL, /* Undef 2 */
3344 NULL, /* Undef 1 */
3345 NULL, /* Undef 0 */
3346
3347 0, /* insert_before_id - place plugin before this mon */
3348
3349 NULL, /* Handle if a plugin, filled in by GKrellM */
3350 NULL /* path if a plugin, filled in by GKrellM */
3351 };
3352
3353 GkrellmMonitor *
gkrellm_init_timer_monitor(void)3354 gkrellm_init_timer_monitor(void)
3355 {
3356 if (!mon_net)
3357 return NULL;
3358 monitor_timer.name = _(monitor_timer.name);
3359 timer_style_id = gkrellm_add_meter_style(&monitor_timer, TIMER_STYLE_NAME);
3360 mon_timer = &monitor_timer;
3361 net_data_dir = gkrellm_make_data_file_name("net", NULL);
3362 reset_mday = 1;
3363 return &monitor_timer;
3364 }
3365
3366