3198 lines
83 KiB
C
3198 lines
83 KiB
C
/* GKrellM
|
|
| Copyright (C) 1999-2007 Bill Wilson
|
|
|
|
|
| Author: Bill Wilson billw@gkrellm.net
|
|
| Latest versions might be found at: http://gkrellm.net
|
|
|
|
|
|
|
|
| GKrellM is free software: you can redistribute it and/or modify it
|
|
| under the terms of the GNU General Public License as published by
|
|
| the Free Software Foundation, either version 3 of the License, or
|
|
| (at your option) any later version.
|
|
|
|
|
| GKrellM is distributed in the hope that it will be useful, but WITHOUT
|
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
| License for more details.
|
|
|
|
|
| You should have received a copy of the GNU General Public License
|
|
| along with this program. If not, see http://www.gnu.org/licenses/
|
|
*/
|
|
|
|
#include "gkrellm.h"
|
|
#include "gkrellm-sysdeps.h"
|
|
#include "gkrellm-private.h"
|
|
|
|
|
|
#define PPP_LOCK_FILE "LCK..modem"
|
|
|
|
#define TIMER_TYPE_NONE 0
|
|
#define TIMER_TYPE_PPP 1
|
|
#define TIMER_TYPE_IPPP 2
|
|
#define TIMER_TYPE_SERVER 3
|
|
|
|
|
|
#define N_DAY_STATS 31
|
|
#define N_WEEK_STATS 26
|
|
#define N_MONTH_STATS 12
|
|
|
|
typedef struct
|
|
{
|
|
gchar *date;
|
|
gdouble rx,
|
|
tx;
|
|
gint connect_time;
|
|
}
|
|
NetStat;
|
|
|
|
enum StatType
|
|
{
|
|
DAY_STAT,
|
|
WEEK_STAT,
|
|
MONTH_STAT
|
|
};
|
|
|
|
|
|
typedef struct
|
|
{
|
|
gchar *name;
|
|
GtkWidget *vbox,
|
|
*parent_vbox;
|
|
GtkWidget *enable_button,
|
|
*force_button,
|
|
*alert_button,
|
|
*label_entry;
|
|
GkrellmChart *chart;
|
|
GkrellmChartdata *rx_cd,
|
|
*tx_cd;
|
|
GkrellmDecal *rxled,
|
|
*txled;
|
|
|
|
/* All known net interfaces are in the net_mon_list. Only interfaces
|
|
| which are up or forced up and are config enabled will actually have
|
|
| a chart created, unless the interface is linked to the timer button.
|
|
| A linked interface always has a chart created for it regardless
|
|
| of the up state but it will have a chart that may not be
|
|
| visible if the interface is down (ppp) or the connect state is
|
|
| hangup (ippp).
|
|
*/
|
|
gboolean locked; /* True if linked to timer button or forced up */
|
|
|
|
GkrellmChartconfig *chart_config;
|
|
gboolean enabled,
|
|
chart_labels,
|
|
force_up,
|
|
real;
|
|
|
|
gchar *label;
|
|
|
|
GkrellmAlert *alert;
|
|
GtkWidget *alert_config_rx_button,
|
|
*alert_config_tx_button;
|
|
gboolean alert_uses_rx,
|
|
alert_uses_tx;
|
|
|
|
gulong rx_old,
|
|
tx_old;
|
|
gint rx_current,
|
|
tx_current;
|
|
gdouble rx_totalA,
|
|
rx_totalB,
|
|
tx_totalA,
|
|
tx_totalB;
|
|
|
|
NetStat day_stats[N_DAY_STATS],
|
|
week_stats[N_WEEK_STATS],
|
|
month_stats[N_MONTH_STATS];
|
|
|
|
gboolean show_totalB,
|
|
totals_shown,
|
|
reset_button_in,
|
|
stats_button_in,
|
|
mouse_in_chart,
|
|
new_text_format;
|
|
GkrellmLauncher launch;
|
|
GtkWidget *launch_entry,
|
|
*tooltip_entry;
|
|
|
|
gboolean up,
|
|
up_prev,
|
|
up_event,
|
|
down_event;
|
|
|
|
gulong rx,
|
|
tx;
|
|
}
|
|
NetMon;
|
|
|
|
|
|
static void cb_alert_config(GkrellmAlert *ap, NetMon *net);
|
|
static void cb_alert_config_create(GkrellmAlert *ap, GtkWidget *vbox,
|
|
NetMon *net);
|
|
static void net_stat_init(NetMon *net);
|
|
|
|
typedef struct
|
|
{
|
|
gchar *name;
|
|
gint type;
|
|
}
|
|
TimerType;
|
|
|
|
|
|
static GList *net_mon_list;
|
|
static GList *net_mon_sys_list;
|
|
static GList *timer_defaults_list;
|
|
static gchar *lock_directory;
|
|
static gchar *net_data_dir;
|
|
|
|
static void (*read_net_data)();
|
|
static void (*check_net_routes)();
|
|
static gboolean (*isdn_is_online)();
|
|
|
|
static gboolean net_use_routed;
|
|
static gboolean net_config_use_routed;
|
|
|
|
static gint reset_mday;
|
|
|
|
static gint
|
|
strcmp_net_name(NetMon *net1, NetMon *net2)
|
|
{
|
|
gchar *s;
|
|
gint n, n1, n2, len;
|
|
|
|
for (s = net1->name; *s; ++s)
|
|
if (isdigit((unsigned char)*s))
|
|
break;
|
|
if (!*s)
|
|
return strcmp(net1->name, net2->name);
|
|
n1 = atoi(s);
|
|
len = s - net1->name;
|
|
n = strncmp(net1->name, net2->name, len);
|
|
if (n == 0)
|
|
{
|
|
n2 = atoi(net2->name + len);
|
|
if (n1 < n2)
|
|
n = -1;
|
|
else if (n1 > n2)
|
|
n = 1;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static NetMon *
|
|
new_net(gchar *name)
|
|
{
|
|
NetMon *net;
|
|
|
|
net = g_new0(NetMon, 1);
|
|
net->name = g_strdup(name);
|
|
if (strcmp(name, "lo"))
|
|
net->enabled = TRUE; /* All except lo default to enabled */
|
|
net->chart_labels = TRUE;
|
|
net->label = g_strdup("");
|
|
net->launch.command = g_strdup("");
|
|
net->launch.tooltip_comment = g_strdup("");
|
|
net->alert_uses_rx = net->alert_uses_tx = TRUE;
|
|
net_mon_list = g_list_insert_sorted(net_mon_list, net,
|
|
(GCompareFunc) strcmp_net_name);
|
|
|
|
net_stat_init(net);
|
|
|
|
return net;
|
|
}
|
|
|
|
static NetMon *
|
|
lookup_net(gchar *name)
|
|
{
|
|
NetMon *net;
|
|
GList *list;
|
|
|
|
if (!name)
|
|
return NULL;
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!strcmp(net->name, name))
|
|
return net;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/* ------------- Net monitor to system dependent interface ------------- */
|
|
|
|
void
|
|
gkrellm_net_client_divert(void (*read_func)(), void (*check_routes)(),
|
|
gboolean (*isdn_online_func)())
|
|
{
|
|
read_net_data = read_func;
|
|
check_net_routes = check_routes;
|
|
isdn_is_online = isdn_online_func;
|
|
}
|
|
|
|
static gboolean
|
|
setup_net_interface(void)
|
|
{
|
|
if (!read_net_data && !_GK.client_mode && gkrellm_sys_net_init())
|
|
{
|
|
read_net_data = gkrellm_sys_net_read_data;
|
|
check_net_routes = gkrellm_sys_net_check_routes;
|
|
isdn_is_online = gkrellm_sys_net_isdn_online;
|
|
}
|
|
return read_net_data ? TRUE : FALSE;
|
|
}
|
|
|
|
gchar *
|
|
gkrellm_net_mon_first(void)
|
|
{
|
|
gchar *name = NULL;
|
|
|
|
net_mon_sys_list = net_mon_list;
|
|
if (net_mon_sys_list)
|
|
{
|
|
name = ((NetMon *) (net_mon_sys_list->data))->name;
|
|
net_mon_sys_list = net_mon_sys_list->next;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
gchar
|
|
*gkrellm_net_mon_next(void)
|
|
{
|
|
gchar *name = NULL;
|
|
|
|
if (net_mon_sys_list)
|
|
{
|
|
name = ((NetMon *) (net_mon_sys_list->data))->name;
|
|
net_mon_sys_list = net_mon_sys_list->next;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_use_routed(gboolean real_routed)
|
|
{
|
|
/* real_routed should only ever be FALSE when called from client.c to
|
|
| handle the server sysdep net code not using routed mode while the
|
|
| client <-> server interface will always use routed mode.
|
|
*/
|
|
net_use_routed = TRUE;
|
|
net_config_use_routed = real_routed;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_routed_event(gchar *name, gboolean routed)
|
|
{
|
|
NetMon *net;
|
|
|
|
if (!net_use_routed)
|
|
return;
|
|
if ((net = lookup_net(name)) == NULL)
|
|
net = new_net(name);
|
|
if (routed)
|
|
net->up_event = TRUE;
|
|
else
|
|
net->down_event = TRUE;
|
|
net->up = routed;
|
|
net->real = TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_assign_data(gchar *name, gulong rx, gulong tx)
|
|
{
|
|
NetMon *net;
|
|
|
|
if ((net = lookup_net(name)) == NULL)
|
|
net = new_net(name);
|
|
if (GK.second_tick && !net_use_routed)
|
|
net->up = TRUE;
|
|
net->rx = rx;
|
|
net->tx = tx;
|
|
net->real = TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_add_timer_type_ppp(gchar *name)
|
|
{
|
|
TimerType *t;
|
|
|
|
if (!name || !*name || _GK.client_mode)
|
|
return;
|
|
t = g_new0(TimerType, 1);
|
|
t->name = g_strdup(name);
|
|
t->type = TIMER_TYPE_PPP;
|
|
timer_defaults_list = g_list_append(timer_defaults_list, t);
|
|
}
|
|
|
|
void
|
|
gkrellm_net_add_timer_type_ippp(gchar *name)
|
|
{
|
|
TimerType *t;
|
|
|
|
if (!name || !*name || _GK.client_mode)
|
|
return;
|
|
t = g_new0(TimerType, 1);
|
|
t->name = g_strdup(name);
|
|
t->type = TIMER_TYPE_IPPP;
|
|
timer_defaults_list = g_list_append(timer_defaults_list, t);
|
|
}
|
|
|
|
void
|
|
gkrellm_net_set_lock_directory(gchar *dir)
|
|
{
|
|
lock_directory = g_strdup(dir);
|
|
}
|
|
|
|
|
|
/* ======================================================================== */
|
|
/* Exporting net data for plugins */
|
|
|
|
gint
|
|
gkrellm_net_routes(void)
|
|
{
|
|
return g_list_length(net_mon_list);
|
|
}
|
|
|
|
gboolean
|
|
gkrellm_net_stats(gint n, gchar *name, gulong *rx, gulong *tx)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
|
|
list = g_list_nth(net_mon_list, n);
|
|
if (!list)
|
|
return FALSE;
|
|
net = (NetMon *) list->data;
|
|
if (name)
|
|
strcpy(name, net->name);
|
|
if (rx)
|
|
*rx = net->rx;
|
|
if (tx)
|
|
*tx = net->tx;
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_led_positions(gint *x_rx_led, gint *y_rx_led,
|
|
gint *x_tx_led, gint *y_tx_led)
|
|
{
|
|
if (x_rx_led)
|
|
*x_rx_led = _GK.rx_led_x;
|
|
if (y_rx_led)
|
|
*y_rx_led = _GK.rx_led_y;
|
|
if (x_tx_led)
|
|
*x_tx_led = _GK.tx_led_x;
|
|
if (y_tx_led)
|
|
*y_tx_led = _GK.tx_led_y;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
#include "pixmaps/net/decal_net_leds.xpm"
|
|
#include "pixmaps/timer/bg_timer.xpm"
|
|
#include "pixmaps/timer/decal_timer_button.xpm"
|
|
|
|
|
|
#define MIN_GRID_RES 5
|
|
#define MAX_GRID_RES 100000000
|
|
#define DEFAULT_GRID_RES 20000
|
|
|
|
/* States for the timer button are indexes to the corresponding
|
|
| timer button decal frame shown.
|
|
*/
|
|
#define TB_NORMAL 0
|
|
#define TB_PRESSED 1
|
|
#define TB_STANDBY 2
|
|
#define TB_ON 3
|
|
#define N_TB_DECALS 4
|
|
|
|
#define RX_LED 0
|
|
#define TX_LED 1
|
|
|
|
#define RX_OFF 0
|
|
#define RX_ON 1
|
|
#define TX_OFF 2
|
|
#define TX_ON 3
|
|
#define N_LEDS 4
|
|
|
|
static GkrellmMonitor *mon_net;
|
|
static GkrellmMonitor *mon_timer;
|
|
|
|
|
|
static NetMon *net_timed; /* Monitor linked to timer button */
|
|
|
|
GkrellmPanel *timer_panel; /* For the timer and button */
|
|
|
|
static GtkWidget *net_vbox; /* Where all net monitors live */
|
|
static GtkWidget *dynamic_net_vbox;
|
|
static GtkWidget *timer_vbox;
|
|
|
|
static GkrellmPiximage *bg_timer_piximage,
|
|
*decal_net_led_piximage,
|
|
*decal_timer_button_piximage;
|
|
|
|
static GkrellmStyle *bg_timer_style;
|
|
|
|
static GdkPixmap *decal_net_led_pixmap;
|
|
static GdkBitmap *decal_net_led_mask;
|
|
|
|
static GdkPixmap *decal_timer_button_pixmap;
|
|
static GdkBitmap *decal_timer_button_mask;
|
|
|
|
static GkrellmDecal *time_decal,
|
|
*seconds_decal,
|
|
*button_decal;
|
|
|
|
/* These 3 decals will be drawn on net charts when mouse is in a chart and
|
|
| the chart has a rx and/or tx total drawn. They won't live in a panel
|
|
| so must be managed differently from decals on a panel.
|
|
*/
|
|
static GkrellmDecal *decal_totalA,
|
|
*decal_totalB,
|
|
*decal_reset;
|
|
static GkrellmDecal *decal_stats;
|
|
|
|
static gchar *timer_on_command;
|
|
static gchar *timer_off_command;
|
|
static gchar *timer_button_iface;
|
|
static gint timer_button_enabled;
|
|
static gint last_time = -1;
|
|
|
|
|
|
static gint timer_button_type = TIMER_TYPE_NONE,
|
|
timer_button_state,
|
|
timer_button_old_state,
|
|
last_timer_command;
|
|
|
|
static gboolean timer_seconds;
|
|
|
|
static gint check_connect_state,
|
|
net_stats_window_height;
|
|
|
|
static gint ascent,
|
|
ascent_alt,
|
|
sec_pad;
|
|
|
|
static time_t net_timer0;
|
|
|
|
static gint net_style_id,
|
|
timer_style_id;
|
|
|
|
static GkrellmSizeAbbrev stats_bytes_abbrev[] =
|
|
{
|
|
{ KB_SIZE(1), 1, "%.0f" },
|
|
{ KB_SIZE(10), KB_SIZE(1), "%.1fKB" },
|
|
{ MB_SIZE(1), KB_SIZE(1), "%.2fKB" },
|
|
{ MB_SIZE(10), MB_SIZE(1), "%.3fMB" },
|
|
{ MB_SIZE(100), MB_SIZE(1), "%.2fMB" },
|
|
{ GB_SIZE(1), MB_SIZE(1), "%.2fMB" },
|
|
{ GB_SIZE(10), GB_SIZE(1), "%.3fGB" },
|
|
{ GB_SIZE(100), GB_SIZE(1), "%.2fGB" },
|
|
{ TB_SIZE(1), GB_SIZE(1), "%.2fGB" },
|
|
{ TB_SIZE(10), TB_SIZE(1), "%.3fTB" },
|
|
{ TB_SIZE(100), TB_SIZE(1), "%.3fTB" },
|
|
{ TB_SIZE(1000), TB_SIZE(1), "%.2fTB" }
|
|
};
|
|
|
|
#define NET_DATA_VERSION 2
|
|
|
|
#define SATURDAY 6
|
|
#define SUNDAY 0
|
|
|
|
static gchar days_in_month[12] =
|
|
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
|
|
|
|
/* Called from client.c
|
|
*/
|
|
void
|
|
gkrellm_net_server_has_timer(void)
|
|
{
|
|
timer_button_type = TIMER_TYPE_SERVER;
|
|
}
|
|
|
|
static void
|
|
draw_led(NetMon *net, int rxtx, int led_index)
|
|
{
|
|
GkrellmPanel *p;
|
|
GkrellmDecal *led;
|
|
|
|
if (!net->chart)
|
|
return;
|
|
p = net->chart->panel;
|
|
if (rxtx == RX_LED)
|
|
led = net->rxled;
|
|
else
|
|
led = net->txled;
|
|
|
|
gkrellm_draw_decal_pixmap(p, led, led_index);
|
|
}
|
|
|
|
static void
|
|
draw_timer(GkrellmPanel *p, gint seconds, gint force)
|
|
{
|
|
static gint prev_minute = -1,
|
|
prev_hour = -1;
|
|
gint minutes, hours, w;
|
|
gchar buf[32], buf_sec[16];
|
|
|
|
last_time = seconds;
|
|
hours = seconds / 60 / 60;
|
|
minutes = (seconds / 60) % 60;
|
|
seconds = seconds % 60;
|
|
snprintf(buf, sizeof(buf), "%2d:%02d", hours, minutes);
|
|
snprintf(buf_sec, sizeof(buf_sec), "%02d", seconds);
|
|
|
|
if (prev_minute != minutes || prev_hour != hours || force)
|
|
{
|
|
w = gkrellm_gdk_string_width(time_decal->text_style.font, buf);
|
|
if (timer_seconds && w + seconds_decal->w + sec_pad <= time_decal->w)
|
|
{
|
|
time_decal->x_off = time_decal->w - w - seconds_decal->w - sec_pad
|
|
- time_decal->text_style.effect;
|
|
gkrellm_make_decal_visible(p, seconds_decal);
|
|
}
|
|
else
|
|
{
|
|
time_decal->x_off = time_decal->w - w
|
|
- time_decal->text_style.effect;
|
|
if (time_decal->x_off < 0)
|
|
time_decal->x_off = 0;
|
|
gkrellm_make_decal_invisible(p, seconds_decal);
|
|
}
|
|
}
|
|
prev_minute = minutes;
|
|
prev_hour = hours;
|
|
|
|
gkrellm_draw_decal_text(p, time_decal, buf,
|
|
force ? -1 : (hours * 60 + minutes));
|
|
|
|
if (gkrellm_is_decal_visible(seconds_decal))
|
|
gkrellm_draw_decal_text(p, seconds_decal, buf_sec,
|
|
force ? -1 : seconds);
|
|
|
|
gkrellm_draw_panel_layers(timer_panel);
|
|
}
|
|
|
|
/* --------- net stats window -----------
|
|
*/
|
|
enum
|
|
{
|
|
DATE_COLUMN,
|
|
RX_COLUMN,
|
|
TX_COLUMN,
|
|
TOTAL_COLUMN,
|
|
TIME_COLUMN,
|
|
N_STATS_COLUMNS
|
|
};
|
|
|
|
static GtkTreeModel *
|
|
stats_model_create(NetMon *net, NetStat *ns, gint n_stats)
|
|
{
|
|
GtkListStore *store;
|
|
GtkTreeIter iter;
|
|
gchar rx[64], tx[64], total[64], time[64];
|
|
gint i, hours, minutes;
|
|
|
|
store = gtk_list_store_new(N_STATS_COLUMNS,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
|
|
for (i = 0; i < n_stats; ++i, ++ns)
|
|
{
|
|
if (i > 0 && !strncmp(ns->date, "---", 3))
|
|
continue;
|
|
gkrellm_format_size_abbrev(rx, sizeof(rx), (gfloat) ns->rx,
|
|
&stats_bytes_abbrev[0],
|
|
sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
|
|
gkrellm_format_size_abbrev(tx, sizeof(tx), (gfloat) ns->tx,
|
|
&stats_bytes_abbrev[0],
|
|
sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
|
|
gkrellm_format_size_abbrev(total, sizeof(total),
|
|
(gfloat) (ns->rx + ns->tx),
|
|
&stats_bytes_abbrev[0],
|
|
sizeof(stats_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
|
|
minutes = ns->connect_time / 60;
|
|
hours = minutes / 60;
|
|
minutes %= 60;
|
|
snprintf(time, sizeof(time), "%4d:%02d", hours, minutes);
|
|
|
|
gtk_list_store_append(store, &iter);
|
|
gtk_list_store_set(store, &iter,
|
|
DATE_COLUMN, ns->date,
|
|
RX_COLUMN, rx,
|
|
TX_COLUMN, tx,
|
|
TOTAL_COLUMN, total,
|
|
TIME_COLUMN, time,
|
|
-1);
|
|
}
|
|
return GTK_TREE_MODEL(store);
|
|
}
|
|
|
|
static gint
|
|
net_stats_window_configure_cb(GtkWidget *widget, GdkEventConfigure *ev,
|
|
gpointer data)
|
|
{
|
|
net_stats_window_height = widget->allocation.height;
|
|
gkrellm_config_modified();
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
net_stats_close_cb(GtkWidget *widget, GtkWidget *stats_window)
|
|
{
|
|
gtk_widget_destroy(stats_window);
|
|
}
|
|
|
|
static void
|
|
net_stats_page(GtkWidget *vbox, NetMon *net,
|
|
NetStat *ns, gint n_stats, gchar *period)
|
|
{
|
|
GtkTreeView *treeview;
|
|
GtkTreeModel *model;
|
|
GtkTreeSelection *selection;
|
|
GtkCellRenderer *renderer;
|
|
gint i;
|
|
|
|
model = stats_model_create(net, ns, n_stats);
|
|
treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
|
|
g_object_unref(model);
|
|
gtk_tree_view_set_rules_hint(treeview, TRUE);
|
|
|
|
renderer = gtk_cell_renderer_text_new();
|
|
gtk_tree_view_insert_column_with_attributes(treeview, -1, period,
|
|
renderer, "text", DATE_COLUMN, NULL);
|
|
|
|
renderer = gtk_cell_renderer_text_new();
|
|
gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Received"),
|
|
renderer, "text", RX_COLUMN, NULL);
|
|
|
|
renderer = gtk_cell_renderer_text_new();
|
|
gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Transmitted"),
|
|
renderer, "text", TX_COLUMN, NULL);
|
|
|
|
renderer = gtk_cell_renderer_text_new();
|
|
gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Total"),
|
|
renderer, "text", TOTAL_COLUMN, NULL);
|
|
|
|
for (i = 0; i < n_stats; ++i)
|
|
if (ns[i].connect_time > 0)
|
|
{
|
|
renderer = gtk_cell_renderer_text_new();
|
|
gtk_tree_view_insert_column_with_attributes(treeview, -1,
|
|
_("Connect Time"),
|
|
renderer, "text", TIME_COLUMN, NULL);
|
|
break;
|
|
}
|
|
selection = gkrellm_gtk_scrolled_selection(treeview, vbox,
|
|
GTK_SELECTION_NONE,
|
|
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC,
|
|
NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
net_stats_window_show(NetMon *net)
|
|
{
|
|
GtkWidget *stats_window, *tabs, *main_vbox;
|
|
GtkWidget *vbox, *hbox, *button, *sep;
|
|
gchar buf[64];
|
|
|
|
snprintf(buf, sizeof(buf), _("%s Statistics"), net->name);
|
|
|
|
stats_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_title(GTK_WINDOW(stats_window), buf);
|
|
gtk_window_set_wmclass(GTK_WINDOW(stats_window),
|
|
"Gkrellm_netstats", "Gkrellm");
|
|
|
|
g_signal_connect(G_OBJECT(stats_window), "configure_event",
|
|
G_CALLBACK(net_stats_window_configure_cb), NULL);
|
|
gtk_window_set_default_size(GTK_WINDOW(stats_window),
|
|
-1, net_stats_window_height);
|
|
|
|
main_vbox = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 4);
|
|
gtk_container_add(GTK_CONTAINER(stats_window), main_vbox);
|
|
|
|
tabs = gtk_notebook_new();
|
|
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
|
|
gtk_box_pack_start(GTK_BOX(main_vbox), tabs, TRUE, TRUE, 0);
|
|
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Daily"));
|
|
net_stats_page(vbox, net, &net->day_stats[0], N_DAY_STATS, _("Date"));
|
|
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Weekly"));
|
|
net_stats_page(vbox, net, &net->week_stats[0], N_WEEK_STATS,
|
|
_("Week Ending"));
|
|
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Monthly"));
|
|
net_stats_page(vbox, net, &net->month_stats[0], N_MONTH_STATS,
|
|
_("Month"));
|
|
|
|
sep = gtk_hseparator_new();
|
|
gtk_box_pack_start(GTK_BOX(main_vbox), sep, FALSE, FALSE, 3);
|
|
|
|
hbox = gtk_hbutton_box_new();
|
|
gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
|
|
gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 4);
|
|
button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
|
g_signal_connect(G_OBJECT(button), "clicked",
|
|
G_CALLBACK(net_stats_close_cb), stats_window);
|
|
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show_all(stats_window);
|
|
}
|
|
|
|
|
|
static gint
|
|
get_connect_state(void)
|
|
{
|
|
struct stat st;
|
|
gchar buf[256];
|
|
gint state = TB_NORMAL;
|
|
static gint old_state;
|
|
|
|
switch (timer_button_type)
|
|
{
|
|
case TIMER_TYPE_NONE:
|
|
case TIMER_TYPE_SERVER:
|
|
break;
|
|
case TIMER_TYPE_PPP:
|
|
if (net_timed->up)
|
|
state = TB_ON;
|
|
else if (lock_directory && *lock_directory)
|
|
{
|
|
snprintf(buf, sizeof(buf),
|
|
"%s/%s", lock_directory, PPP_LOCK_FILE);
|
|
if (stat(buf, &st) == 0)
|
|
state = TB_STANDBY;
|
|
else
|
|
{
|
|
/* If lock file is ttySx, then user can make a link:
|
|
| ln -s ~/.gkrellm2/LCK..modem lock_directory/LCK..ttySx
|
|
*/
|
|
snprintf(buf, sizeof(buf), "%s/%s/%s",
|
|
gkrellm_homedir(), GKRELLM_DIR, PPP_LOCK_FILE);
|
|
if (stat(buf, &st) == 0)
|
|
state = TB_STANDBY;
|
|
}
|
|
}
|
|
break;
|
|
case TIMER_TYPE_IPPP:
|
|
if (isdn_is_online && (*isdn_is_online)())
|
|
state = net_timed->up ? TB_ON : TB_STANDBY;
|
|
break;
|
|
}
|
|
if ((_GK.debug_level & DEBUG_TIMER) && state != old_state)
|
|
g_print(_("get_connect_state changed from %d to %d (check=%d)\n"),
|
|
old_state, state, check_connect_state);
|
|
old_state = state;
|
|
return state;
|
|
}
|
|
|
|
static void
|
|
get_connect_time(void)
|
|
{
|
|
struct stat st;
|
|
gchar buf[256];
|
|
time_t t = 0;
|
|
|
|
switch (timer_button_type)
|
|
{
|
|
case TIMER_TYPE_NONE:
|
|
case TIMER_TYPE_SERVER:
|
|
break;
|
|
case TIMER_TYPE_PPP:
|
|
snprintf(buf, sizeof(buf), "/var/run/%s.pid", timer_button_iface);
|
|
if (stat(buf, &st) == 0)
|
|
t = st.st_mtime;
|
|
break;
|
|
case TIMER_TYPE_IPPP:
|
|
break;
|
|
}
|
|
if (t > 0)
|
|
net_timer0 = t;
|
|
else
|
|
time(&net_timer0);
|
|
}
|
|
|
|
static void
|
|
set_timer_button_state(gint decal_state)
|
|
{
|
|
timer_button_old_state = timer_button_state;
|
|
timer_button_state = decal_state;
|
|
gkrellm_draw_decal_pixmap(timer_panel, button_decal, decal_state);
|
|
gkrellm_draw_panel_layers(timer_panel);
|
|
|
|
if ( (_GK.debug_level & DEBUG_TIMER)
|
|
&& timer_button_state != timer_button_old_state
|
|
)
|
|
g_print(_("set_timer_button_state from %d to %d (check=%d)\n"),
|
|
timer_button_old_state, timer_button_state, check_connect_state);
|
|
}
|
|
|
|
static void
|
|
update_timer_button_monitor(void)
|
|
{
|
|
if (timer_button_state == TB_PRESSED)
|
|
return;
|
|
if ( (_GK.debug_level & DEBUG_TIMER) && net_timed
|
|
&& timer_button_type != TIMER_TYPE_NONE
|
|
&& (net_timed->up_event || net_timed->down_event)
|
|
)
|
|
g_print(_("update_timer_button net_timed old_state=%d new_state=%d\n"),
|
|
net_timed->up_event, net_timed->down_event);
|
|
switch (timer_button_type)
|
|
{
|
|
case TIMER_TYPE_NONE:
|
|
if (timer_button_state == TB_ON)
|
|
draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
|
|
break;
|
|
|
|
case TIMER_TYPE_PPP:
|
|
if (net_timed->up)
|
|
{
|
|
set_timer_button_state(TB_ON);
|
|
check_connect_state = FALSE;
|
|
if (net_timed->up_event)
|
|
get_connect_time();
|
|
}
|
|
else if (net_timed->down_event)
|
|
set_timer_button_state(TB_NORMAL);
|
|
if (check_connect_state)
|
|
set_timer_button_state(get_connect_state());
|
|
|
|
if (net_timed->up)
|
|
draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
|
|
break;
|
|
|
|
case TIMER_TYPE_IPPP:
|
|
/* get all isdn status from get_connect_state because the
|
|
| net_timed->up can be UP even with isdn line not connected.
|
|
*/
|
|
set_timer_button_state(get_connect_state());
|
|
if ( timer_button_state != TB_NORMAL
|
|
&& timer_button_old_state == TB_NORMAL
|
|
)
|
|
time(&net_timer0); /* New session just started */
|
|
if (timer_button_state != TB_NORMAL)
|
|
draw_timer(timer_panel, (int) (time(0) - net_timer0), 0);
|
|
break;
|
|
|
|
case TIMER_TYPE_SERVER:
|
|
/* Button state is independent of displayed timer
|
|
*/
|
|
draw_timer(timer_panel, gkrellm_client_server_get_net_timer(), 0);
|
|
break;
|
|
}
|
|
if (net_timed && net_timed->up)
|
|
{
|
|
net_timed->day_stats[0].connect_time += 1;
|
|
net_timed->week_stats[0].connect_time += 1;
|
|
net_timed->month_stats[0].connect_time += 1;
|
|
}
|
|
}
|
|
|
|
static void
|
|
stale_pppd_files_debug(void)
|
|
{
|
|
struct stat st;
|
|
gchar buf[256];
|
|
|
|
snprintf(buf, sizeof(buf), "/var/run/%s.pid", timer_button_iface);
|
|
if (stat(buf, &st) == 0 && !net_timed->up)
|
|
g_print(_(" **** Stale pppd pppX.pid file detected!\n"));
|
|
}
|
|
|
|
static gint
|
|
in_button(GkrellmDecal *d, GdkEventButton *ev)
|
|
{
|
|
if (ev->x > d->x && ev->x <= d->x + d->w)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static gint save_tb_state;
|
|
|
|
static gint
|
|
cb_timer_button_press(GtkWidget *widget, GdkEventButton *ev)
|
|
{
|
|
if (ev->button != 1 || !in_button(DECAL(timer_panel), ev))
|
|
return FALSE;
|
|
if (timer_button_state != TB_PRESSED) /* button bounce? */
|
|
save_tb_state = timer_button_state;
|
|
set_timer_button_state(TB_PRESSED);
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
cb_timer_button_release(GtkWidget *widget, GdkEventButton *ev)
|
|
{
|
|
gint tstate, timer_command;
|
|
|
|
if (timer_button_state != TB_PRESSED)
|
|
return FALSE;
|
|
set_timer_button_state(save_tb_state);
|
|
if (! in_button(DECAL(timer_panel), ev))
|
|
return FALSE;
|
|
|
|
switch (timer_button_type)
|
|
{
|
|
case TIMER_TYPE_NONE:
|
|
case TIMER_TYPE_SERVER:
|
|
if (timer_button_state == TB_NORMAL)
|
|
{
|
|
if (*timer_on_command != '\0')
|
|
g_spawn_command_line_async(timer_on_command, NULL);
|
|
set_timer_button_state(TB_ON);
|
|
time(&net_timer0);
|
|
}
|
|
else
|
|
{
|
|
if (*timer_off_command != '\0')
|
|
g_spawn_command_line_async(timer_off_command, NULL);
|
|
set_timer_button_state(TB_NORMAL);
|
|
}
|
|
break;
|
|
|
|
case TIMER_TYPE_PPP:
|
|
case TIMER_TYPE_IPPP:
|
|
check_connect_state = TRUE;
|
|
tstate = get_connect_state();
|
|
if (_GK.debug_level & DEBUG_TIMER)
|
|
stale_pppd_files_debug();
|
|
if (tstate == TB_NORMAL)
|
|
timer_command = ON;
|
|
else if (tstate == TB_ON)
|
|
timer_command = OFF;
|
|
else /* tstate == TB_STANDBY */
|
|
{
|
|
/* For some, pppd is leaving stale LCK..modem (and ppp0.pid)
|
|
| files which can fool gkrellm. So the question is, do I
|
|
| launch off or on command here? Since I can't trust
|
|
| TB_STANDBY to mean pppd is running, I'll just base it on
|
|
| state info.
|
|
*/
|
|
if (last_timer_command == ON)
|
|
{
|
|
timer_command = OFF;
|
|
if (timer_button_type == TIMER_TYPE_PPP)
|
|
set_timer_button_state(TB_NORMAL);
|
|
check_connect_state = FALSE;
|
|
draw_led(net_timed, RX_LED, RX_OFF); /* Noise */
|
|
draw_led(net_timed, TX_LED, TX_OFF);
|
|
}
|
|
else
|
|
timer_command = ON;
|
|
}
|
|
if (timer_command == ON && *timer_on_command != '\0')
|
|
g_spawn_command_line_async(timer_on_command, NULL);
|
|
if (timer_command == OFF && *timer_off_command != '\0')
|
|
g_spawn_command_line_async(timer_off_command, NULL);
|
|
last_timer_command = timer_command;
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* A timed_net (linked to the timer button) always has a panel
|
|
| visible, and the Chart visibility is toggled based on net up state.
|
|
*/
|
|
static void
|
|
timed_net_visibility(void)
|
|
{
|
|
NetMon *net = net_timed;
|
|
gboolean net_is_up,
|
|
chart_is_visible;
|
|
|
|
if (!net || !net->chart)
|
|
return;
|
|
chart_is_visible = gkrellm_is_chart_visible(net->chart);
|
|
|
|
/* For ippp, the route may always be up, so base a up state on the
|
|
| route being alive and the line status being connected (timer button
|
|
| state)
|
|
*/
|
|
if (timer_button_type == TIMER_TYPE_IPPP)
|
|
net_is_up = (net->up && timer_button_state != TB_NORMAL);
|
|
else
|
|
net_is_up = net->up;
|
|
|
|
if ((net->force_up || net_is_up) && !chart_is_visible)
|
|
gkrellm_chart_show(net->chart, TRUE); /* Make sure panel is shown */
|
|
else if (!net->force_up && !net_is_up && chart_is_visible)
|
|
{
|
|
gkrellm_chart_hide(net->chart, FALSE); /* Don't hide the panel */
|
|
|
|
/* Save data whenever net has transitioned to a "not up" state.
|
|
| Don't have the info to do this when there's a force_up and in
|
|
| this case just rely on the every six hour tick data save.
|
|
*/
|
|
gkrellm_net_save_data();
|
|
}
|
|
}
|
|
|
|
|
|
static gint
|
|
net_expose_event(GtkWidget *widget, GdkEventExpose *ev)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
GdkPixmap *pixmap = NULL;
|
|
|
|
if (timer_panel->drawing_area == widget)
|
|
pixmap = timer_panel->pixmap;
|
|
else
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!net->chart || !net->chart->panel) /* A disabled iface */
|
|
continue;
|
|
if (net->chart->drawing_area == widget)
|
|
pixmap = net->chart->pixmap;
|
|
else if (net->chart->panel->drawing_area == widget)
|
|
pixmap = net->chart->panel->pixmap;
|
|
if (pixmap)
|
|
break;
|
|
}
|
|
if (pixmap)
|
|
gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), pixmap,
|
|
ev->area.x, ev->area.y, ev->area.x, ev->area.y,
|
|
ev->area.width, ev->area.height);
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
map_x(gint x, gint width)
|
|
{
|
|
gint xnew, chart_width;
|
|
|
|
xnew = x;
|
|
chart_width = gkrellm_chart_width();
|
|
if (x < 0)
|
|
xnew += chart_width - width;
|
|
return xnew;
|
|
}
|
|
|
|
static gint
|
|
grid_resolution_default(NetMon *net)
|
|
{
|
|
gchar *s = net->name;
|
|
gint res;
|
|
|
|
if (! strncmp(s, "ppp", 3))
|
|
res = 2000;
|
|
#if defined(__FreeBSD__)
|
|
else if (! strncmp(s, "tun", 3))
|
|
res = 2000;
|
|
#endif
|
|
else if (! strncmp(s, "plip", 3) || ! strncmp(s, "ippp", 4))
|
|
res = 5000;
|
|
else if (! strncmp(s, "eth", 3))
|
|
res = 20000;
|
|
else
|
|
res = 10000;
|
|
return res;
|
|
}
|
|
|
|
static void
|
|
setup_net_scaling(GkrellmChartconfig *cf, NetMon *net)
|
|
{
|
|
GkrellmChart *cp = net->chart;
|
|
gint grids, res;
|
|
|
|
grids = gkrellm_get_chartconfig_fixed_grids(cf);
|
|
if (!grids)
|
|
grids = FULL_SCALE_GRIDS;
|
|
|
|
res = gkrellm_get_chartconfig_grid_resolution(cf);
|
|
KRELL(cp->panel)->full_scale = res * grids / gkrellm_update_HZ();
|
|
}
|
|
|
|
static void
|
|
destroy_chart(NetMon *net)
|
|
{
|
|
GkrellmChart *cp;
|
|
|
|
if (!net)
|
|
return;
|
|
cp = net->chart;
|
|
if (cp)
|
|
{
|
|
net->launch.button = NULL;
|
|
net->launch.tooltip = NULL;
|
|
g_free(cp->panel->textstyle);
|
|
cp->panel->textstyle = NULL;
|
|
gkrellm_chart_destroy(cp);
|
|
gtk_widget_destroy(net->vbox);
|
|
net->chart = NULL;
|
|
net->vbox = NULL;
|
|
net->parent_vbox = NULL;
|
|
}
|
|
net->locked = FALSE;
|
|
}
|
|
|
|
|
|
static GkrellmSizeAbbrev current_bytes_abbrev[] =
|
|
{
|
|
{ KB_SIZE(1), 1, "%.0f" },
|
|
{ KB_SIZE(20), KB_SIZE(1), "%.1fK" },
|
|
{ MB_SIZE(1), KB_SIZE(1), "%.0fK" },
|
|
{ MB_SIZE(20), MB_SIZE(1), "%.1fM" },
|
|
{ GB_SIZE(1), MB_SIZE(1), "%.0fM" },
|
|
{ GB_SIZE(20), GB_SIZE(1), "%.1fG" },
|
|
{ TB_SIZE(1), GB_SIZE(1), "%.0fG" },
|
|
{ TB_SIZE(20), TB_SIZE(1), "%.1fT" },
|
|
{ TB_SIZE(1000), TB_SIZE(1), "%.0fT" }
|
|
};
|
|
|
|
static GkrellmSizeAbbrev total_bytes_abbrev[] =
|
|
{
|
|
{ KB_SIZE(100), 1, "%.0f" },
|
|
{ MB_SIZE(1), KB_SIZE(1), "%.1fK" },
|
|
{ MB_SIZE(10), MB_SIZE(1), "%.3fM" },
|
|
{ MB_SIZE(100), MB_SIZE(1), "%.2fM" },
|
|
{ GB_SIZE(1), MB_SIZE(1), "%.1fM" },
|
|
{ GB_SIZE(10), GB_SIZE(1), "%.3fG" },
|
|
{ GB_SIZE(100), GB_SIZE(1), "%.2fG" },
|
|
{ TB_SIZE(1), GB_SIZE(1), "%.1fG" },
|
|
{ TB_SIZE(10), TB_SIZE(1), "%.3fT" },
|
|
{ TB_SIZE(100), TB_SIZE(1), "%.2fT" },
|
|
{ TB_SIZE(1000), TB_SIZE(1), "%.1fT" }
|
|
};
|
|
|
|
#define DEFAULT_TEXT_FORMAT "$T\\b\\c\\f$L"
|
|
|
|
static gchar *text_format,
|
|
*text_format_locale;
|
|
|
|
static void
|
|
format_net_data(NetMon *net, gchar *src_string, gchar *buf, gint size)
|
|
{
|
|
GkrellmChart *cp;
|
|
gchar c, *s, *s1, *result;
|
|
gint len, bytes;
|
|
gdouble fbytes;
|
|
gboolean month, day, week;
|
|
|
|
if (!buf || size < 1)
|
|
return;
|
|
--size;
|
|
*buf = '\0';
|
|
result = buf;
|
|
|
|
if (!src_string)
|
|
return;
|
|
cp = net->chart;
|
|
net->totals_shown = FALSE;
|
|
|
|
if ((_GK.debug_level & DEBUG_CHART_TEXT))
|
|
printf("net chart text: %s\n", src_string);
|
|
|
|
for (s = src_string; *s != '\0' && size > 0; ++s)
|
|
{
|
|
len = 1;
|
|
month = week = day = FALSE;
|
|
if (*s == '$' && *(s + 1) != '\0')
|
|
{
|
|
bytes = -1;
|
|
fbytes = -1.0;
|
|
if ((c = *(s + 2)) == 'm') /* cumulative modifiers */
|
|
month = TRUE;
|
|
else if (c == 'w')
|
|
week = TRUE;
|
|
else if (c == 'd')
|
|
day = TRUE;
|
|
|
|
if ((c = *(s + 1)) == 'T')
|
|
bytes = net->rx_current + net->tx_current;
|
|
else if (c == 'M')
|
|
bytes = gkrellm_get_chart_scalemax(cp);
|
|
else if (c == 't')
|
|
bytes = net->tx_current;
|
|
else if (c == 'r')
|
|
bytes = net->rx_current;
|
|
else if (c == 'o')
|
|
{
|
|
if (month)
|
|
fbytes = net->month_stats[0].tx;
|
|
else if (week)
|
|
fbytes = net->week_stats[0].tx;
|
|
else if (day)
|
|
fbytes = net->day_stats[0].tx;
|
|
else
|
|
fbytes = net->show_totalB
|
|
? net->tx_totalB : net->tx_totalA;
|
|
}
|
|
else if (c == 'i')
|
|
{
|
|
if (month)
|
|
fbytes = net->month_stats[0].rx;
|
|
else if (week)
|
|
fbytes = net->week_stats[0].rx;
|
|
else if (day)
|
|
fbytes = net->day_stats[0].rx;
|
|
else
|
|
fbytes = net->show_totalB
|
|
? net->rx_totalB : net->rx_totalA;
|
|
}
|
|
else if (c == 'O')
|
|
{
|
|
if (month)
|
|
fbytes = net->month_stats[0].rx + net->month_stats[0].tx;
|
|
else if (week)
|
|
fbytes = net->week_stats[0].rx + net->week_stats[0].tx;
|
|
else if (day)
|
|
fbytes = net->day_stats[0].rx + net->day_stats[0].tx;
|
|
else
|
|
fbytes = net->show_totalB
|
|
? (net->rx_totalB + net->tx_totalB)
|
|
: (net->rx_totalA + net->tx_totalA);
|
|
}
|
|
else if (c == 'L')
|
|
{
|
|
if (!*(net->label))
|
|
s1 = " ";
|
|
else
|
|
s1 = net->label;
|
|
len = snprintf(buf, size, "%s", s1);
|
|
}
|
|
else if (c == 'I')
|
|
len = snprintf(buf, size, "%s", net->name);
|
|
else if (c == 'H')
|
|
len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name());
|
|
else if ((s1 = gkrellm_plugin_get_exported_label(mon_net, c,
|
|
net->name)) != NULL)
|
|
len = snprintf(buf, size, "%s", s1);
|
|
else
|
|
{
|
|
*buf = *s;
|
|
if (size > 1)
|
|
{
|
|
*(buf + 1) = *(s + 1);
|
|
++len;
|
|
}
|
|
}
|
|
if (bytes >= 0)
|
|
len = gkrellm_format_size_abbrev(buf, size, (gfloat) bytes,
|
|
¤t_bytes_abbrev[0],
|
|
sizeof(current_bytes_abbrev) / sizeof(GkrellmSizeAbbrev));
|
|
else if (fbytes >= 0)
|
|
{
|
|
len = gkrellm_format_size_abbrev(buf, size, (gfloat) fbytes,
|
|
&total_bytes_abbrev[0],
|
|
sizeof(total_bytes_abbrev) /sizeof(GkrellmSizeAbbrev));
|
|
if (!day && !week && !month)
|
|
net->totals_shown = TRUE;
|
|
}
|
|
++s;
|
|
if (day || week || month)
|
|
++s;
|
|
}
|
|
else
|
|
*buf = *s;
|
|
size -= len;
|
|
buf += len;
|
|
}
|
|
*buf = '\0';
|
|
|
|
if ((_GK.debug_level & DEBUG_CHART_TEXT))
|
|
printf(" : %s\n", result);
|
|
}
|
|
|
|
static void
|
|
draw_net_chart_labels(NetMon *net)
|
|
{
|
|
GkrellmChart *cp = net->chart;
|
|
gchar buf[128];
|
|
|
|
if (!net->chart_labels)
|
|
return;
|
|
format_net_data(net, text_format_locale, buf, sizeof(buf));
|
|
if (!net->new_text_format)
|
|
gkrellm_chart_reuse_text_format(cp);
|
|
net->new_text_format = FALSE;
|
|
gkrellm_draw_chart_text(cp, net_style_id, buf);
|
|
}
|
|
|
|
static void
|
|
cb_command_process(GkrellmAlert *alert, gchar *src, gchar *dst, gint len,
|
|
NetMon *net)
|
|
{
|
|
format_net_data(net, src, dst, len);
|
|
}
|
|
|
|
static void
|
|
draw_chart_buttons(NetMon *net)
|
|
{
|
|
gint frame, x, y;
|
|
|
|
if ( net->totals_shown && net->chart_labels
|
|
&& decal_totalA && decal_totalB && decal_reset
|
|
)
|
|
{
|
|
x = gkrellm_chart_width() - 2 * decal_totalA->w;
|
|
y = 2;
|
|
|
|
frame = net->show_totalB ? D_MISC_BUTTON_OUT : D_MISC_BUTTON_IN;
|
|
gkrellm_draw_decal_pixmap(NULL, decal_totalA, frame);
|
|
gkrellm_draw_decal_on_chart(net->chart, decal_totalA, x, y);
|
|
|
|
frame = net->show_totalB ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
|
|
gkrellm_draw_decal_pixmap(NULL, decal_totalB, frame);
|
|
gkrellm_draw_decal_on_chart(net->chart, decal_totalB,
|
|
x + decal_totalA->w, y);
|
|
|
|
frame = net->reset_button_in ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
|
|
gkrellm_draw_decal_pixmap(NULL, decal_reset, frame);
|
|
gkrellm_draw_decal_on_chart(net->chart, decal_reset,
|
|
x + decal_totalA->w, y + decal_totalA->h + 4);
|
|
}
|
|
if (decal_stats)
|
|
{
|
|
x = gkrellm_chart_width() - decal_stats->w;
|
|
y = net->chart->h - decal_stats->h;
|
|
frame = net->stats_button_in ? D_MISC_BUTTON_IN : D_MISC_BUTTON_OUT;
|
|
gkrellm_draw_decal_pixmap(NULL, decal_stats, frame);
|
|
gkrellm_draw_decal_on_chart(net->chart, decal_stats, x, y);
|
|
}
|
|
}
|
|
|
|
static void
|
|
refresh_net_chart(NetMon *net)
|
|
{
|
|
if (!net->chart)
|
|
return;
|
|
gkrellm_draw_chartdata(net->chart);
|
|
draw_net_chart_labels(net);
|
|
if (net->mouse_in_chart)
|
|
draw_chart_buttons(net);
|
|
gkrellm_draw_chart_to_screen(net->chart);
|
|
}
|
|
|
|
|
|
static gint
|
|
cb_chart_press(GtkWidget *widget, GdkEventButton *ev, NetMon *net)
|
|
{
|
|
gboolean check_button;
|
|
|
|
check_button = net->chart_labels && net->totals_shown;
|
|
if (check_button && gkrellm_in_decal(decal_totalA, ev))
|
|
{
|
|
net->show_totalB = FALSE;
|
|
refresh_net_chart(net);
|
|
}
|
|
else if (check_button && gkrellm_in_decal(decal_totalB, ev))
|
|
{
|
|
net->show_totalB = TRUE;
|
|
refresh_net_chart(net);
|
|
}
|
|
else if (check_button && gkrellm_in_decal(decal_reset, ev))
|
|
{
|
|
net->reset_button_in = TRUE;
|
|
refresh_net_chart(net);
|
|
}
|
|
else if (gkrellm_in_decal(decal_stats, ev))
|
|
{
|
|
net->stats_button_in = TRUE;
|
|
refresh_net_chart(net);
|
|
}
|
|
else if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS)
|
|
{
|
|
net->chart_labels = !net->chart_labels;
|
|
gkrellm_config_modified();
|
|
refresh_net_chart(net);
|
|
}
|
|
else if ( ev->button == 3
|
|
|| (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS)
|
|
)
|
|
gkrellm_chartconfig_window_create(net->chart);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
cb_chart_release(GtkWidget *widget, GdkEventButton *ev, NetMon *net)
|
|
{
|
|
if (!net->reset_button_in && !net->stats_button_in)
|
|
return FALSE;
|
|
if (net->stats_button_in && gkrellm_in_decal(decal_stats, ev))
|
|
net_stats_window_show(net);
|
|
if (net->reset_button_in && gkrellm_in_decal(decal_reset, ev))
|
|
{
|
|
if (net->show_totalB)
|
|
net->rx_totalB = net->tx_totalB = 0;
|
|
else
|
|
net->rx_totalA = net->tx_totalA = 0;
|
|
}
|
|
net->reset_button_in = FALSE;
|
|
net->stats_button_in = FALSE;
|
|
refresh_net_chart(net);
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
cb_chart_enter(GtkWidget *w, GdkEventButton *ev, NetMon *net)
|
|
{
|
|
net->mouse_in_chart = TRUE;
|
|
draw_chart_buttons(net);
|
|
gkrellm_draw_chart_to_screen(net->chart);
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
cb_chart_leave(GtkWidget *w, GdkEventButton *ev, NetMon *net)
|
|
{
|
|
net->mouse_in_chart = FALSE;
|
|
net->reset_button_in = FALSE;
|
|
net->stats_button_in = FALSE;
|
|
refresh_net_chart(net);
|
|
return FALSE;
|
|
}
|
|
|
|
static gint
|
|
cb_panel_press(GtkWidget *widget, GdkEventButton *ev)
|
|
{
|
|
if (ev->button == 3)
|
|
gkrellm_open_config_window(mon_net);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Make sure net charts appear in same order as the sorted net_mon_list
|
|
*/
|
|
static void
|
|
net_chart_reorder(NetMon *new_net)
|
|
{
|
|
NetMon *net;
|
|
GList *list;
|
|
gint i;
|
|
|
|
for (i = 0, list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (net->parent_vbox != new_net->parent_vbox)
|
|
continue;
|
|
if (net == new_net)
|
|
break;
|
|
++i;
|
|
}
|
|
if (!list || !list->next)
|
|
return;
|
|
gtk_box_reorder_child(GTK_BOX(new_net->parent_vbox), new_net->vbox, i);
|
|
}
|
|
|
|
static void
|
|
create_net_monitor(GtkWidget *vbox, NetMon *net, gint first_create)
|
|
{
|
|
GkrellmStyle *style;
|
|
GkrellmChart *cp;
|
|
GkrellmPanel *p;
|
|
|
|
if (first_create)
|
|
{
|
|
net->parent_vbox = vbox;
|
|
net->vbox = gtk_vbox_new(FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), net->vbox, FALSE, FALSE, 0);
|
|
|
|
net->chart = gkrellm_chart_new0();
|
|
net->chart->panel = gkrellm_panel_new0();
|
|
net->chart->panel->textstyle = gkrellm_textstyle_new0();
|
|
net_chart_reorder(net);
|
|
}
|
|
cp = net->chart;
|
|
p = cp->panel;
|
|
|
|
gkrellm_chart_create(net->vbox, mon_net, cp, &net->chart_config);
|
|
net->tx_cd = gkrellm_add_default_chartdata(cp, _("tx bytes"));
|
|
net->rx_cd = gkrellm_add_default_chartdata(cp, _("rx bytes"));
|
|
gkrellm_set_draw_chart_function(cp, refresh_net_chart, net);
|
|
|
|
gkrellm_chartconfig_fixed_grids_connect(cp->config,
|
|
setup_net_scaling, net);
|
|
gkrellm_chartconfig_grid_resolution_connect(cp->config,
|
|
setup_net_scaling, net);
|
|
gkrellm_chartconfig_grid_resolution_adjustment(cp->config, TRUE,
|
|
0, (gfloat) MIN_GRID_RES, (gfloat) MAX_GRID_RES, 0, 0, 0, 0);
|
|
|
|
gkrellm_chartconfig_grid_resolution_label(cp->config,
|
|
_("rx/tx bytes per sec"));
|
|
if (gkrellm_get_chartconfig_grid_resolution(cp->config) < MIN_GRID_RES)
|
|
gkrellm_set_chartconfig_grid_resolution(cp->config,
|
|
grid_resolution_default(net));
|
|
gkrellm_alloc_chartdata(cp);
|
|
|
|
style = gkrellm_panel_style(net_style_id);
|
|
gkrellm_create_krell(p, gkrellm_krell_panel_piximage(net_style_id), style);
|
|
|
|
net->rxled = gkrellm_create_decal_pixmap(p, decal_net_led_pixmap,
|
|
decal_net_led_mask, N_LEDS, style, 0, _GK.rx_led_y);
|
|
net->rxled->x = map_x(_GK.rx_led_x, net->rxled->w);
|
|
|
|
net->txled = gkrellm_create_decal_pixmap(p, decal_net_led_pixmap,
|
|
decal_net_led_mask, N_LEDS, style, 0, _GK.tx_led_y);
|
|
net->txled->x = map_x(_GK.tx_led_x, net->txled->w);
|
|
|
|
*(p->textstyle) = *gkrellm_panel_textstyle(net_style_id);
|
|
if (strlen(net->name) > 5)
|
|
p->textstyle->font = gkrellm_panel_alt_textstyle(net_style_id)->font;
|
|
|
|
gkrellm_panel_configure(p, net->name, style);
|
|
gkrellm_panel_create(net->vbox, mon_net, p);
|
|
|
|
setup_net_scaling(cp->config, net);
|
|
|
|
net->new_text_format = TRUE;
|
|
if (first_create)
|
|
{
|
|
g_signal_connect(G_OBJECT (cp->drawing_area), "expose_event",
|
|
G_CALLBACK(net_expose_event), NULL);
|
|
g_signal_connect(G_OBJECT(cp->drawing_area), "button_press_event",
|
|
G_CALLBACK(cb_chart_press), net);
|
|
g_signal_connect(G_OBJECT(cp->drawing_area), "button_release_event",
|
|
G_CALLBACK(cb_chart_release), net);
|
|
g_signal_connect(G_OBJECT(cp->drawing_area), "enter_notify_event",
|
|
G_CALLBACK(cb_chart_enter), net);
|
|
g_signal_connect(G_OBJECT(cp->drawing_area), "leave_notify_event",
|
|
G_CALLBACK(cb_chart_leave), net);
|
|
|
|
g_signal_connect(G_OBJECT (p->drawing_area), "expose_event",
|
|
G_CALLBACK(net_expose_event), NULL);
|
|
g_signal_connect(G_OBJECT(p->drawing_area), "button_press_event",
|
|
G_CALLBACK(cb_panel_press), NULL);
|
|
|
|
gtk_widget_show_all(net->vbox);
|
|
}
|
|
else
|
|
refresh_net_chart(net);
|
|
|
|
gkrellm_setup_launcher(p, &net->launch, CHART_PANEL_TYPE, 0);
|
|
|
|
draw_led(net, RX_LED, RX_OFF);
|
|
draw_led(net, TX_LED, TX_OFF);
|
|
|
|
if (net->force_up)
|
|
net->locked = TRUE;
|
|
}
|
|
|
|
static void
|
|
net_timer_visibility(void)
|
|
{
|
|
if (timer_button_enabled)
|
|
{
|
|
gkrellm_panel_show(timer_panel);
|
|
gkrellm_spacers_show(mon_timer);
|
|
}
|
|
else
|
|
{
|
|
gkrellm_panel_hide(timer_panel);
|
|
gkrellm_spacers_hide(mon_timer);
|
|
}
|
|
}
|
|
|
|
|
|
static gint
|
|
days_in_year(gint y)
|
|
{
|
|
if((y % 4) == 0)
|
|
return 366;
|
|
return 365;
|
|
}
|
|
|
|
/* Adjust a tm date structure to reference its next day.
|
|
*/
|
|
static void
|
|
next_day(struct tm *t)
|
|
{
|
|
if ((t->tm_wday += 1) > SATURDAY)
|
|
t->tm_wday = SUNDAY;
|
|
if ((t->tm_yday += 1) >= days_in_year(t->tm_year) )
|
|
{
|
|
t->tm_year += 1;
|
|
t->tm_yday = 0;
|
|
}
|
|
if ((t->tm_mday += 1) > days_in_month[t->tm_mon])
|
|
{
|
|
if ( t->tm_mon == 1
|
|
&& (((gint)t->tm_year - 80) % 4) == 0
|
|
&& t->tm_mday == 29)
|
|
;
|
|
else
|
|
{
|
|
if ((t->tm_mon += 1) > 11)
|
|
t->tm_mon = 0;
|
|
t->tm_mday = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
net_accounting_month_new(struct tm *tm)
|
|
{
|
|
if ( tm->tm_mday == reset_mday
|
|
|| ( reset_mday > days_in_month[tm->tm_mon]
|
|
&& tm->tm_mday == 1
|
|
)
|
|
)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_save_data(void)
|
|
{
|
|
FILE *f;
|
|
GList *list;
|
|
struct tm *tm = gkrellm_get_current_time();
|
|
NetMon *net;
|
|
gchar fname[256];
|
|
gint i;
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!net->enabled)
|
|
continue;
|
|
snprintf(fname, sizeof(fname), "%s%c%s", net_data_dir,
|
|
G_DIR_SEPARATOR, net->name);
|
|
if ((f = fopen(fname, "w")) == NULL)
|
|
continue;
|
|
fprintf(f, "%d\n", NET_DATA_VERSION);
|
|
fputs("wday mday month yday year\n", f);
|
|
fprintf(f, "%d %d %d %d %d\n", tm->tm_wday,
|
|
tm->tm_mday, tm->tm_mon, tm->tm_yday, tm->tm_year);
|
|
|
|
fputs("[daily]\n", f);
|
|
for (i = 0; i < N_DAY_STATS; ++i)
|
|
fprintf(f, "\"%s\" %.0f %.0f %d\n", net->day_stats[i].date,
|
|
net->day_stats[i].rx, net->day_stats[i].tx,
|
|
net->day_stats[i].connect_time);
|
|
fputs("[weekly]\n", f);
|
|
for (i = 0; i < N_WEEK_STATS; ++i)
|
|
fprintf(f, "\"%s\" %.0f %.0f %d\n", net->week_stats[i].date,
|
|
net->week_stats[i].rx, net->week_stats[i].tx,
|
|
net->week_stats[i].connect_time);
|
|
fputs("[monthly]\n", f);
|
|
for (i = 0; i < N_MONTH_STATS; ++i)
|
|
fprintf(f, "\"%s\" %.0f %.0f %d\n", net->month_stats[i].date,
|
|
net->month_stats[i].rx, net->month_stats[i].tx,
|
|
net->month_stats[i].connect_time);
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
static gchar *
|
|
utf8_string(gchar *string)
|
|
{
|
|
gchar *utf8 = NULL;
|
|
|
|
if ( g_utf8_validate(string, -1, NULL)
|
|
|| (utf8 = g_locale_to_utf8(string, -1, NULL, NULL, NULL)) == NULL
|
|
)
|
|
utf8 = g_strdup(string);
|
|
|
|
return utf8;
|
|
}
|
|
|
|
static void
|
|
net_stat_set_date_string(NetStat *ns, enum StatType stat_type, struct tm *t)
|
|
{
|
|
struct tm tm = *t,
|
|
tmx;
|
|
gchar *utf8, buf[32], bufa[32], bufb[32];
|
|
|
|
if (stat_type == DAY_STAT)
|
|
{
|
|
strftime(buf, sizeof(buf), "%F", &tm); /* %Y-%m-%d (the ISO 8601) */
|
|
}
|
|
else if (stat_type == WEEK_STAT)
|
|
{
|
|
while (tm.tm_wday != SATURDAY)
|
|
next_day(&tm);
|
|
strftime(buf, sizeof(buf), "%F", &tm);
|
|
}
|
|
else if (stat_type == MONTH_STAT)
|
|
{
|
|
if (reset_mday == 1)
|
|
strftime(buf, sizeof(buf), "%B", &tm); /* full month name */
|
|
else
|
|
{
|
|
tmx = tm;
|
|
if (tm.tm_mday < reset_mday)
|
|
{
|
|
tmx.tm_mon -= 1;
|
|
if (tmx.tm_mon < 0)
|
|
{
|
|
tmx.tm_mon = 11;
|
|
tmx.tm_year -= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tm.tm_mon += 1;
|
|
if (tm.tm_mon > 11)
|
|
{
|
|
tm.tm_mon = 0;
|
|
tm.tm_year += 1;
|
|
}
|
|
}
|
|
tmx.tm_mday = reset_mday;
|
|
tm.tm_mday = reset_mday - 1;
|
|
if (tmx.tm_mday > days_in_month[tmx.tm_mon])
|
|
tmx.tm_mday = days_in_month[tmx.tm_mon];
|
|
if (tm.tm_mday > days_in_month[tm.tm_mon])
|
|
tm.tm_mday = days_in_month[tm.tm_mon];
|
|
strftime(bufa, sizeof(bufa), "%b %e", &tmx);
|
|
strftime(bufb, sizeof(bufb), "%b %e", &tm);
|
|
snprintf(buf, sizeof(buf), "%s - %s", bufa, bufb);
|
|
}
|
|
}
|
|
else
|
|
return;
|
|
|
|
g_free(ns->date);
|
|
utf8 = utf8_string(buf);
|
|
ns->date = utf8 ? utf8 : g_strdup("??");
|
|
}
|
|
|
|
static void
|
|
net_stat_init(NetMon *net)
|
|
{
|
|
struct tm *tm = gkrellm_get_current_time();
|
|
gint i;
|
|
|
|
for (i = 0; i < N_DAY_STATS; ++i)
|
|
net->day_stats[i].date = g_strdup("---");
|
|
for (i = 0; i < N_WEEK_STATS; ++i)
|
|
net->week_stats[i].date = g_strdup("---");
|
|
for (i = 0; i < N_MONTH_STATS; ++i)
|
|
net->month_stats[i].date = g_strdup("---");
|
|
|
|
net_stat_set_date_string(&net->day_stats[0], DAY_STAT, tm);
|
|
net_stat_set_date_string(&net->week_stats[0], WEEK_STAT, tm);
|
|
net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, tm);
|
|
}
|
|
|
|
static void
|
|
net_stats_shift_down(NetStat *ns, gint n_stats, enum StatType stat_type)
|
|
{
|
|
gint d;
|
|
|
|
g_free(ns[n_stats - 1].date);
|
|
|
|
for (d = n_stats - 1; d > 0; --d)
|
|
ns[d] = ns[d - 1];
|
|
ns->rx = ns->tx = 0.0;
|
|
ns->connect_time = 0;
|
|
ns->date = NULL;
|
|
net_stat_set_date_string(ns, stat_type, gkrellm_get_current_time());
|
|
}
|
|
|
|
static void
|
|
load_net_data(void)
|
|
{
|
|
FILE *f;
|
|
GList *list;
|
|
struct tm *tm = gkrellm_get_current_time();
|
|
NetMon *net;
|
|
NetStat *ns = NULL;
|
|
gchar buf[128], fname[256], date[32];
|
|
gint wday, mday, month, yday, year, version;
|
|
gint day_delta, month_delta, n_stats = 0;
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
snprintf(fname, sizeof(fname), "%s%c%s", net_data_dir,
|
|
G_DIR_SEPARATOR, net->name);
|
|
if ((f = fopen(fname, "r")) == NULL)
|
|
continue;
|
|
fgets(buf, sizeof(buf), f);
|
|
if (sscanf(buf, "%d\n", &version) != 1)
|
|
{
|
|
fclose(f);
|
|
continue;
|
|
}
|
|
|
|
fgets(buf, sizeof(buf), f); /* Comment line */
|
|
fgets(buf, sizeof(buf), f);
|
|
sscanf(buf, "%d %d %d %d %d", &wday, &mday, &month, &yday, &year);
|
|
|
|
if (version == 1)
|
|
{
|
|
struct tm tmx = *gkrellm_get_current_time();
|
|
|
|
tmx.tm_wday = wday;
|
|
tmx.tm_mday = mday;
|
|
tmx.tm_mon = month;
|
|
tmx.tm_yday = yday;
|
|
tmx.tm_year = year;
|
|
|
|
fgets(buf, sizeof(buf), f); /* day */
|
|
fgets(buf, sizeof(buf), f);
|
|
sscanf(buf, "%lf %lf",
|
|
&net->day_stats[0].rx, &net->day_stats[0].tx);
|
|
fgets(buf, sizeof(buf), f); /* week */
|
|
fgets(buf, sizeof(buf), f);
|
|
sscanf(buf, "%lf %lf",
|
|
&net->week_stats[0].rx, &net->week_stats[0].tx);
|
|
fgets(buf, sizeof(buf), f); /* month */
|
|
fgets(buf, sizeof(buf), f);
|
|
sscanf(buf, "%lf %lf",
|
|
&net->month_stats[0].rx, &net->month_stats[0].tx);
|
|
|
|
net_stat_set_date_string(&net->day_stats[0], DAY_STAT, &tmx);
|
|
net_stat_set_date_string(&net->week_stats[0], WEEK_STAT, &tmx);
|
|
net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, &tmx);
|
|
|
|
if ( net == net_timed
|
|
&& fgets(buf, sizeof(buf), f) /* connect day*/
|
|
)
|
|
{
|
|
fgets(buf, sizeof(buf), f);
|
|
sscanf(buf, "%d %d %d",
|
|
&net->day_stats[0].connect_time,
|
|
&net->week_stats[0].connect_time,
|
|
&net->month_stats[0].connect_time);
|
|
}
|
|
|
|
}
|
|
else if (version == NET_DATA_VERSION)
|
|
{
|
|
while (fgets(buf, sizeof(buf), f) != NULL)
|
|
{
|
|
if (!strncmp(buf, "[daily]", 7))
|
|
{
|
|
ns = &net->day_stats[0];
|
|
n_stats = N_DAY_STATS;
|
|
}
|
|
else if (!strncmp(buf, "[weekly]", 8))
|
|
{
|
|
ns = &net->week_stats[0];
|
|
n_stats = N_WEEK_STATS;
|
|
}
|
|
else if (!strncmp(buf, "[monthly]", 9))
|
|
{
|
|
ns = &net->month_stats[0];
|
|
n_stats = N_MONTH_STATS;
|
|
}
|
|
else if ( ns && n_stats > 0
|
|
&& sscanf(buf, "\"%31[^\"]\" %lf %lf %d",
|
|
date, &ns->rx, &ns->tx, &ns->connect_time) == 4
|
|
)
|
|
{
|
|
gkrellm_dup_string(&ns->date, date);
|
|
++ns;
|
|
--n_stats;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fclose(f);
|
|
continue;
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
month_delta = (tm->tm_year * 12 + tm->tm_mon) - (year * 12 + month);
|
|
if (month_delta == 0)
|
|
day_delta = tm->tm_mday - mday;
|
|
else if (month_delta == 1)
|
|
day_delta = days_in_month[month] - mday + tm->tm_mday;
|
|
else
|
|
day_delta = 7; /* max compared to is 6 */
|
|
|
|
if (day_delta > 0)
|
|
net_stats_shift_down(&net->day_stats[0], N_DAY_STATS, DAY_STAT);
|
|
|
|
if (wday + day_delta != tm->tm_wday)
|
|
net_stats_shift_down(&net->week_stats[0], N_WEEK_STATS, WEEK_STAT);
|
|
|
|
if ( ( tm->tm_mday < reset_mday
|
|
&& ( (month_delta > 1)
|
|
|| (month_delta == 1 && mday < reset_mday)
|
|
)
|
|
)
|
|
|| ( tm->tm_mday >= reset_mday
|
|
&& ( (month_delta > 0)
|
|
|| (month_delta == 0 && mday < reset_mday)
|
|
)
|
|
)
|
|
)
|
|
net_stats_shift_down(&net->month_stats[0], N_MONTH_STATS,
|
|
MONTH_STAT);
|
|
}
|
|
}
|
|
|
|
|
|
#define SEC_PAD 0
|
|
|
|
static void
|
|
create_net_timer(GtkWidget *vbox, gint first_create)
|
|
{
|
|
GkrellmPanel *p;
|
|
GkrellmStyle *style;
|
|
GkrellmTextstyle *ts, *ts_alt;
|
|
GkrellmMargin *m;
|
|
GkrellmBorder *tb;
|
|
gint top_margin, bot_margin;
|
|
gint x, y, w, h, w_avail;
|
|
|
|
if (first_create)
|
|
timer_panel = gkrellm_panel_new0();
|
|
p = timer_panel;
|
|
|
|
style = gkrellm_meter_style(timer_style_id);
|
|
ts = gkrellm_meter_textstyle(timer_style_id);
|
|
ts_alt = gkrellm_meter_alt_textstyle(timer_style_id);
|
|
m = gkrellm_get_style_margins(style);
|
|
tb = &bg_timer_style->border;
|
|
|
|
button_decal = gkrellm_create_decal_pixmap(p, decal_timer_button_pixmap,
|
|
decal_timer_button_mask, N_TB_DECALS, style, -1, -1);
|
|
button_decal->x = gkrellm_chart_width() - m->right - button_decal->w;
|
|
|
|
w_avail = button_decal->x - m->left - 3;
|
|
if (bg_timer_piximage)
|
|
w_avail -= tb->left + tb->right;
|
|
w = gkrellm_gdk_string_width(ts->font, "0000:0000");
|
|
sec_pad = gkrellm_gdk_string_width(ts->font, "0") * 2 / 3;
|
|
if (w > w_avail)
|
|
w = w_avail;
|
|
|
|
time_decal = gkrellm_create_decal_text(p, "0:", ts, style, -1, -1, w);
|
|
seconds_decal = gkrellm_create_decal_text(p, "00",
|
|
ts_alt, style, -1, -1, 0);
|
|
|
|
gkrellm_panel_configure(p, NULL, style);
|
|
|
|
/* Some special work needed here if there is a bg_timer. I have so
|
|
| far the time_decal and button_decal fitting inside top/bottom margins.
|
|
| If I add bg_timer borders to time_decal height and that ends up higher
|
|
| than button_decal, I will need to grow the panel height.
|
|
*/
|
|
h = time_decal->h;
|
|
if (bg_timer_piximage)
|
|
{
|
|
gkrellm_get_top_bottom_margins(style, &top_margin, &bot_margin);
|
|
h += tb->top + tb->bottom;
|
|
time_decal->y += tb->top;
|
|
time_decal->x += tb->left;
|
|
if (h > button_decal->h) /* Need to grow the height ? */
|
|
{
|
|
gkrellm_panel_configure_set_height(p, h + top_margin + bot_margin);
|
|
button_decal->y += (h - button_decal->h) / 2;
|
|
}
|
|
else /* button_decal->y is OK */
|
|
time_decal->y += (button_decal->h - h) / 2;
|
|
}
|
|
else
|
|
{
|
|
/* time_decal and button_decal are initially at same y = top_margin
|
|
*/
|
|
if (time_decal->h > button_decal->h)
|
|
button_decal->y += (time_decal->h - button_decal->h) / 2;
|
|
else
|
|
time_decal->y += (button_decal->h - time_decal->h) / 2;
|
|
}
|
|
|
|
seconds_decal->y = time_decal->y + time_decal->h - seconds_decal->h;
|
|
gkrellm_panel_create(vbox, mon_timer, p);
|
|
|
|
gkrellm_move_decal(p, seconds_decal,
|
|
time_decal->x + time_decal->w - seconds_decal->w,
|
|
seconds_decal->y);
|
|
|
|
if (first_create)
|
|
{
|
|
g_signal_connect(G_OBJECT (p->drawing_area), "expose_event",
|
|
G_CALLBACK(net_expose_event), NULL);
|
|
g_signal_connect(G_OBJECT(p->drawing_area), "button_release_event",
|
|
G_CALLBACK(cb_timer_button_release), NULL);
|
|
g_signal_connect(G_OBJECT(p->drawing_area), "leave_notify_event",
|
|
G_CALLBACK(cb_timer_button_release), NULL);
|
|
g_signal_connect(G_OBJECT(p->drawing_area), "button_press_event",
|
|
G_CALLBACK(cb_timer_button_press), NULL);
|
|
}
|
|
|
|
if (bg_timer_piximage)
|
|
{
|
|
w += tb->left + tb->right;
|
|
x = time_decal->x - tb->left;
|
|
y = time_decal->y - tb->top;
|
|
gkrellm_paste_piximage(bg_timer_piximage, p->pixmap, x, y, w, h);
|
|
gkrellm_paste_piximage(bg_timer_piximage, p->bg_pixmap, x, y, w, h);
|
|
gdk_draw_drawable(p->bg_text_layer_pixmap, _GK.draw1_GC, p->bg_pixmap,
|
|
0, 0, 0, 0, p->w, p->h);
|
|
|
|
}
|
|
|
|
set_timer_button_state(timer_button_state);
|
|
}
|
|
|
|
static void
|
|
update_net(void)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
struct tm *tm;
|
|
GkrellmPanel *p;
|
|
gint bytes;
|
|
gdouble rxd, txd;
|
|
|
|
/* If sysdep code is not reporting route up/down events, then
|
|
| gkrellm_net_assign_data() sets a net as up if data is assigned for it.
|
|
| So, once a second, compare a net up state before a data read to the
|
|
| state after a read and use that to internally generate up/down events.
|
|
| If sysdep code assigns data even if a net is not routed, then there
|
|
| will be no automatic chart toggling and charts will always be visible
|
|
| if enabled.
|
|
*/
|
|
if (GK.second_tick)
|
|
{
|
|
if (!net_use_routed)
|
|
{
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
net->up_prev = net->up;
|
|
net->up = FALSE;
|
|
}
|
|
}
|
|
else
|
|
(*check_net_routes)();
|
|
}
|
|
(*read_net_data)();
|
|
if (GK.second_tick && !net_use_routed)
|
|
{
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (net->up && !net->up_prev)
|
|
net->up_event = TRUE;
|
|
else if (!net->up && net->up_prev)
|
|
net->down_event = TRUE;
|
|
}
|
|
}
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!net->chart)
|
|
continue;
|
|
p = net->chart->panel;
|
|
if (net->up || net->force_up)
|
|
{
|
|
if (net->rx > net->rx_old)
|
|
draw_led(net, RX_LED, RX_ON);
|
|
else
|
|
draw_led(net, RX_LED, RX_OFF);
|
|
if (net->tx > net->tx_old)
|
|
draw_led(net, TX_LED, TX_ON);
|
|
else
|
|
draw_led(net, TX_LED, TX_OFF);
|
|
}
|
|
net->rx_old = net->rx;
|
|
net->tx_old = net->tx;
|
|
if (GK.second_tick)
|
|
{
|
|
gkrellm_store_chartdata(net->chart, 0, net->tx, net->rx);
|
|
net->rx_current = gkrellm_get_current_chartdata(net->rx_cd);
|
|
net->tx_current = gkrellm_get_current_chartdata(net->tx_cd);
|
|
rxd = (gdouble) net->rx_current;
|
|
txd = (gdouble) net->tx_current;
|
|
net->rx_totalA += rxd;
|
|
net->tx_totalA += txd;
|
|
net->rx_totalB += rxd;
|
|
net->tx_totalB += txd;
|
|
|
|
if (GK.day_tick)
|
|
{
|
|
tm = gkrellm_get_current_time();
|
|
net_stats_shift_down(&net->day_stats[0], N_DAY_STATS,
|
|
DAY_STAT);
|
|
|
|
if (tm->tm_wday == 0)
|
|
net_stats_shift_down(&net->week_stats[0], N_WEEK_STATS,
|
|
WEEK_STAT);
|
|
|
|
if (net_accounting_month_new(tm))
|
|
net_stats_shift_down(&net->month_stats[0], N_MONTH_STATS,
|
|
MONTH_STAT);
|
|
}
|
|
net->day_stats[0].rx += rxd;
|
|
net->week_stats[0].rx += rxd;
|
|
net->month_stats[0].rx += rxd;
|
|
|
|
net->day_stats[0].tx += txd;
|
|
net->week_stats[0].tx += txd;
|
|
net->month_stats[0].tx += txd;
|
|
|
|
if (net->alert)
|
|
{
|
|
bytes = 0;
|
|
if (net->alert_uses_rx)
|
|
bytes += net->rx_current;
|
|
if (net->alert_uses_tx)
|
|
bytes += net->tx_current;
|
|
gkrellm_check_alert(net->alert, bytes);
|
|
}
|
|
gkrellm_panel_label_on_top_of_decals(p,
|
|
gkrellm_alert_decal_visible(net->alert));
|
|
refresh_net_chart(net);
|
|
}
|
|
gkrellm_update_krell(p, KRELL(p), net->tx + net->rx);
|
|
gkrellm_draw_panel_layers(p);
|
|
}
|
|
if (GK.second_tick)
|
|
{
|
|
update_timer_button_monitor();
|
|
timed_net_visibility();
|
|
if (net_timed && !net_timed->up && !net_timed->force_up)
|
|
{
|
|
draw_led(net_timed, RX_LED, RX_OFF);
|
|
draw_led(net_timed, TX_LED, TX_OFF);
|
|
}
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!net->locked)
|
|
{
|
|
if (net->up_event && !net->chart && net->enabled)
|
|
{
|
|
create_net_monitor(dynamic_net_vbox, net, TRUE);
|
|
gkrellm_pack_side_frames();
|
|
}
|
|
else if (net->down_event && net->chart)
|
|
{
|
|
destroy_chart(net);
|
|
gkrellm_pack_side_frames();
|
|
}
|
|
}
|
|
net->up_event = net->down_event = FALSE;
|
|
}
|
|
}
|
|
if (GK.hour_tick)
|
|
{
|
|
tm = gkrellm_get_current_time();
|
|
if ((tm->tm_hour % 6) == 0)
|
|
gkrellm_net_save_data();
|
|
}
|
|
}
|
|
|
|
/* A timed interface has its chart locked and is forced enabled.
|
|
*/
|
|
static void
|
|
create_timed_monitor(void)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
TimerType *tt;
|
|
|
|
if (_GK.client_mode)
|
|
return;
|
|
|
|
net_timed = NULL;
|
|
timer_button_type = TIMER_TYPE_NONE;
|
|
time(&net_timer0);
|
|
|
|
if (!*timer_button_iface || !strcmp(timer_button_iface, "none"))
|
|
return;
|
|
|
|
/* Making a timed mon out of one that is already up? It needs to be
|
|
| moved to a different vbox, so destroy and create dance.
|
|
*/
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!strcmp(net->name, timer_button_iface))
|
|
{
|
|
destroy_chart(net);
|
|
break;
|
|
}
|
|
}
|
|
if ((net = lookup_net(timer_button_iface)) == NULL)
|
|
net = new_net(timer_button_iface);
|
|
|
|
net->enabled = TRUE;
|
|
net->locked = TRUE;
|
|
create_net_monitor(net_vbox, net, TRUE);
|
|
if (!net->up)
|
|
gkrellm_chart_hide(net->chart, FALSE); /* Don't hide its panel */
|
|
|
|
net_timed = net;
|
|
for (list = timer_defaults_list; list; list = list->next)
|
|
{
|
|
tt = (TimerType *) list->data;
|
|
if (!strncmp(timer_button_iface, tt->name, strlen(tt->name) - 1))
|
|
{
|
|
timer_button_type = tt->type;
|
|
break;
|
|
}
|
|
}
|
|
get_connect_time();
|
|
}
|
|
|
|
|
|
static void
|
|
load_net_extra_piximages(void)
|
|
{
|
|
gchar **xpm;
|
|
gint w, h;
|
|
|
|
/* Check for theme_dir/net/decal_net_leds.png.
|
|
*/
|
|
gkrellm_load_piximage("decal_net_leds", decal_net_leds_xpm,
|
|
&decal_net_led_piximage, NET_STYLE_NAME);
|
|
|
|
w = gdk_pixbuf_get_width(decal_net_led_piximage->pixbuf);
|
|
w *= gkrellm_get_theme_scale();
|
|
|
|
h = gdk_pixbuf_get_height(decal_net_led_piximage->pixbuf) / N_LEDS;
|
|
h *= gkrellm_get_theme_scale();
|
|
|
|
gkrellm_scale_piximage_to_pixmap(decal_net_led_piximage,
|
|
&decal_net_led_pixmap, &decal_net_led_mask, w, h * N_LEDS);
|
|
|
|
/* Check for theme_dir/net/decal_timer_button.png
|
|
*/
|
|
gkrellm_load_piximage("decal_timer_button", decal_timer_button_xpm,
|
|
&decal_timer_button_piximage, TIMER_STYLE_NAME);
|
|
h = gdk_pixbuf_get_height(decal_timer_button_piximage->pixbuf)
|
|
/ N_TB_DECALS;
|
|
h *= gkrellm_get_theme_scale();
|
|
gkrellm_scale_piximage_to_pixmap(decal_timer_button_piximage,
|
|
&decal_timer_button_pixmap, &decal_timer_button_mask,
|
|
-1, h * N_TB_DECALS);
|
|
|
|
/* Here is where I define the net timer panel theme extensions. I ask
|
|
| for a theme extension image:
|
|
| THEME_DIR/timer/bg_timer.png
|
|
| and for a border for it from the gkrellmrc in the format:
|
|
| set_piximage_border timer_bg_timer l,r,t,b
|
|
| There is no default for bg_timer, ie it may end up being NULL.
|
|
*/
|
|
if (!bg_timer_style) /* Used just for the bg_timer border */
|
|
bg_timer_style = gkrellm_style_new0();
|
|
if (bg_timer_piximage)
|
|
gkrellm_destroy_piximage(bg_timer_piximage);
|
|
bg_timer_piximage = NULL;
|
|
xpm = (gkrellm_using_default_theme()) ? bg_timer_xpm : NULL;
|
|
gkrellm_load_piximage("bg_timer", xpm,
|
|
&bg_timer_piximage, TIMER_STYLE_NAME);
|
|
gkrellm_set_gkrellmrc_piximage_border("timer_bg_timer",
|
|
bg_timer_piximage, bg_timer_style);
|
|
}
|
|
|
|
static void
|
|
net_spacer_visibility(void)
|
|
{
|
|
GList *list;
|
|
gboolean enabled = FALSE;
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
if (((NetMon *) list->data)->enabled)
|
|
enabled = TRUE;
|
|
if (timer_button_enabled || enabled)
|
|
gkrellm_spacers_show(mon_net);
|
|
else
|
|
gkrellm_spacers_hide(mon_net);
|
|
}
|
|
|
|
static void
|
|
create_net(GtkWidget *vbox, gint first_create)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
|
|
load_net_extra_piximages();
|
|
|
|
/* Make a couple of vboxes here so I can control the net layout.
|
|
| I want interface linked to the timer button to go last.
|
|
*/
|
|
if (first_create)
|
|
{
|
|
dynamic_net_vbox = gtk_vbox_new(FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), dynamic_net_vbox, FALSE, FALSE, 0);
|
|
gtk_widget_show(dynamic_net_vbox);
|
|
|
|
net_vbox = gtk_vbox_new(FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), net_vbox, FALSE, FALSE, 0);
|
|
gtk_widget_show(net_vbox);
|
|
|
|
(*(read_net_data))(); /* need net up states */
|
|
|
|
create_timed_monitor();
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (net == net_timed)
|
|
continue;
|
|
if ((net->up || net->force_up) && net->enabled)
|
|
create_net_monitor(dynamic_net_vbox, net, first_create);
|
|
}
|
|
load_net_data();
|
|
}
|
|
else
|
|
{
|
|
/* Some decals don't live in a panel, they will be drawn onto
|
|
| charts when needed. So, must destroy them at create events (not
|
|
| done automatically in panel lists) and then recreate them with NULL
|
|
| panel and style pointers.
|
|
*/
|
|
gkrellm_destroy_decal(decal_totalA);
|
|
gkrellm_destroy_decal(decal_totalB);
|
|
gkrellm_destroy_decal(decal_reset);
|
|
gkrellm_destroy_decal(decal_stats);
|
|
decal_totalA = decal_totalB = decal_reset = decal_stats = NULL;
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (net->chart)
|
|
create_net_monitor(NULL, net, 0);
|
|
}
|
|
}
|
|
decal_totalA = gkrellm_create_decal_pixmap(NULL,
|
|
gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
|
|
N_MISC_DECALS, NULL, 0, 0);
|
|
decal_totalB = gkrellm_create_decal_pixmap(NULL,
|
|
gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
|
|
N_MISC_DECALS, NULL, 0, 0);
|
|
|
|
decal_reset = gkrellm_create_decal_pixmap(NULL,
|
|
gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
|
|
N_MISC_DECALS, NULL, 0, 0);
|
|
|
|
decal_stats = gkrellm_create_decal_pixmap(NULL,
|
|
gkrellm_decal_misc_pixmap(), gkrellm_decal_misc_mask(),
|
|
N_MISC_DECALS, NULL, 0, 0);
|
|
|
|
net_spacer_visibility();
|
|
}
|
|
|
|
static void
|
|
create_timer(GtkWidget *vbox, gint first_create)
|
|
{
|
|
timer_vbox = vbox;
|
|
create_net_timer(timer_vbox, first_create);
|
|
ascent = 0;
|
|
ascent_alt = 0;
|
|
if (first_create)
|
|
draw_timer(timer_panel, (int) (time(0) - net_timer0), 1);
|
|
else
|
|
draw_timer(timer_panel, last_time , 1);
|
|
gkrellm_draw_panel_layers(timer_panel);
|
|
net_timer_visibility();
|
|
}
|
|
|
|
#define NET_CONFIG_KEYWORD "net"
|
|
|
|
static void
|
|
cb_alert_trigger(GkrellmAlert *alert, NetMon *net)
|
|
{
|
|
/* Full panel alert, default decal.
|
|
*/
|
|
alert->panel = net->chart->panel;
|
|
}
|
|
|
|
static void
|
|
create_alert(NetMon *net)
|
|
{
|
|
net->alert = gkrellm_alert_create(NULL, net->name,
|
|
_("Bytes per second"),
|
|
TRUE, FALSE, TRUE,
|
|
1e10, 1000, 1000, 10000, 0);
|
|
gkrellm_alert_delay_config(net->alert, 1, 60 * 60, 0);
|
|
|
|
gkrellm_alert_trigger_connect(net->alert, cb_alert_trigger, net);
|
|
gkrellm_alert_config_connect(net->alert, cb_alert_config, net);
|
|
gkrellm_alert_config_create_connect(net->alert,
|
|
cb_alert_config_create, net);
|
|
gkrellm_alert_command_process_connect(net->alert, cb_command_process, net);
|
|
}
|
|
|
|
|
|
static void
|
|
save_net_config(FILE *f)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
if (!net->enabled && !net->real)
|
|
continue;
|
|
fprintf(f, "%s enables %s %d %d %d\n", NET_CONFIG_KEYWORD, net->name,
|
|
net->enabled, net->chart_labels, net->force_up);
|
|
gkrellm_save_chartconfig(f, net->chart_config,
|
|
NET_CONFIG_KEYWORD, net->name);
|
|
if (*net->label)
|
|
fprintf(f, "%s label %s %s\n", NET_CONFIG_KEYWORD,
|
|
net->name, net->label);
|
|
if (*(net->launch.command))
|
|
fprintf(f, "%s launch %s %s\n", NET_CONFIG_KEYWORD,
|
|
net->name, net->launch.command);
|
|
if (*(net->launch.tooltip_comment))
|
|
fprintf(f, "%s tooltip %s %s\n", NET_CONFIG_KEYWORD,
|
|
net->name, net->launch.tooltip_comment);
|
|
if (net->alert)
|
|
{
|
|
gkrellm_save_alertconfig(f, net->alert,
|
|
NET_CONFIG_KEYWORD, net->name);
|
|
fprintf(f, "%s extra_alert_config %s %d %d\n", NET_CONFIG_KEYWORD,
|
|
net->name,
|
|
net->alert_uses_rx, net->alert_uses_tx);
|
|
}
|
|
}
|
|
|
|
if (!_GK.client_mode || timer_button_type != TIMER_TYPE_SERVER)
|
|
fprintf(f, "%s timer_enabled %d\n", NET_CONFIG_KEYWORD,
|
|
timer_button_enabled);
|
|
fprintf(f, "%s timer_seconds %d\n", NET_CONFIG_KEYWORD, timer_seconds);
|
|
if (!_GK.client_mode)
|
|
fprintf(f, "%s timer_iface %s\n", NET_CONFIG_KEYWORD,
|
|
timer_button_iface);
|
|
fprintf(f, "%s timer_on %s\n", NET_CONFIG_KEYWORD, timer_on_command);
|
|
fprintf(f, "%s timer_off %s\n", NET_CONFIG_KEYWORD, timer_off_command);
|
|
fprintf(f, "%s text_format %s\n", NET_CONFIG_KEYWORD, text_format);
|
|
fprintf(f, "%s reset_mday %d\n", NET_CONFIG_KEYWORD, reset_mday);
|
|
fprintf(f, "%s net_stats_window_height %d\n", NET_CONFIG_KEYWORD,
|
|
net_stats_window_height);
|
|
}
|
|
|
|
static void
|
|
load_net_config(gchar *arg)
|
|
{
|
|
NetMon *net;
|
|
gchar config[32], name[32];
|
|
gchar item[CFG_BUFSIZE], item1[CFG_BUFSIZE];
|
|
gboolean enable = TRUE, ch_labels = TRUE, force = FALSE;
|
|
gint n;
|
|
|
|
n = sscanf(arg, "%31s %[^\n]", config, item);
|
|
if (n != 2)
|
|
return;
|
|
|
|
if (!_GK.client_mode || timer_button_type != TIMER_TYPE_SERVER)
|
|
if (!strcmp(config, "timer_enabled") && ! _GK.demo)
|
|
sscanf(item, "%d", &timer_button_enabled);
|
|
|
|
if (!strcmp(config, "timer_seconds"))
|
|
sscanf(item, "%d", &timer_seconds);
|
|
else if (!strcmp(config, "reset_mday"))
|
|
sscanf(item, "%d", &reset_mday);
|
|
else if (!strcmp(config, "net_stats_window_height"))
|
|
sscanf(item, "%d", &net_stats_window_height);
|
|
else if (!strcmp(config, "timer_iface") && !_GK.client_mode)
|
|
{
|
|
if (_GK.demo && !strcmp(item, "none"))
|
|
gkrellm_dup_string(&timer_button_iface, "ppp0");
|
|
else
|
|
gkrellm_dup_string(&timer_button_iface, item);
|
|
}
|
|
else if (!strcmp(config, "timer_on"))
|
|
gkrellm_dup_string(&timer_on_command, item);
|
|
else if (!strcmp(config, "timer_off"))
|
|
gkrellm_dup_string(&timer_off_command, item);
|
|
else if (!strcmp(config, "text_format"))
|
|
gkrellm_locale_dup_string(&text_format, item, &text_format_locale);
|
|
else if (sscanf(item, "%31s %[^\n]", name, item1) == 2)
|
|
{
|
|
if (!strcmp(config, "iface")) /* Hack to get some of 1.0 config */
|
|
{ /* Can't get resolution, label, launch or tooltip */
|
|
sscanf(item1, "%*d %d %*s %d %d", &enable, &ch_labels, &force);
|
|
strcpy(config, "enables");
|
|
sprintf(item1, "%d %d %d", enable, ch_labels, force);
|
|
}
|
|
/* Remaining configs will have a net name
|
|
*/
|
|
if (!strcmp(config, "enables"))
|
|
{
|
|
if ((net = lookup_net(name)) == NULL)
|
|
net = new_net(name);
|
|
sscanf(item1, "%d %d %d", &net->enabled, &net->chart_labels,
|
|
&net->force_up);
|
|
if (!net_use_routed)
|
|
net->force_up = FALSE;
|
|
return;
|
|
}
|
|
if ((net = lookup_net(name)) == NULL)
|
|
return;
|
|
if (!strcmp(config, GKRELLM_CHARTCONFIG_KEYWORD))
|
|
gkrellm_load_chartconfig(&net->chart_config, item1, 2);
|
|
else if (!strcmp(config, GKRELLM_ALERTCONFIG_KEYWORD))
|
|
{
|
|
if (!net->alert)
|
|
create_alert(net);
|
|
gkrellm_load_alertconfig(&net->alert, item1);
|
|
}
|
|
else if (!strcmp(config, "extra_alert_config"))
|
|
sscanf(item1, "%d %d", &net->alert_uses_rx, &net->alert_uses_tx);
|
|
else if (!strcmp(config, "label"))
|
|
gkrellm_dup_string(&net->label, item1);
|
|
else if (!strcmp(config, "launch"))
|
|
gkrellm_dup_string(&net->launch.command, item1);
|
|
else if (!strcmp(config, "tooltip"))
|
|
gkrellm_dup_string(&net->launch.tooltip_comment, item1);
|
|
}
|
|
}
|
|
|
|
|
|
/* -------------- User config interface --------------------- */
|
|
|
|
#define STEP 1
|
|
|
|
static GtkWidget *pon_entry,
|
|
*poff_entry,
|
|
*timer_iface_combo,
|
|
*text_format_combo;
|
|
|
|
static GtkWidget *enable_net_timer_button;
|
|
static GtkWidget *net_timer_seconds_button;
|
|
|
|
static gboolean enable_in_progress;
|
|
|
|
|
|
static void
|
|
sync_chart(NetMon *net)
|
|
{
|
|
/* If enabling, fake an up_event so update_net() will create the chart.
|
|
*/
|
|
if (net->enabled && !net->chart && (net->up || net->force_up))
|
|
net->up_event = TRUE;
|
|
else if ( net->chart
|
|
&& (!net->enabled || (!net->locked && !net->force_up && !net->up))
|
|
)
|
|
destroy_chart(net);
|
|
}
|
|
|
|
static void
|
|
cb_force(GtkWidget *button, NetMon *net)
|
|
{
|
|
if (enable_in_progress)
|
|
return;
|
|
net->force_up = GTK_TOGGLE_BUTTON(button)->active;
|
|
if (net != net_timed)
|
|
net->locked = FALSE;
|
|
sync_chart(net);
|
|
}
|
|
|
|
static void
|
|
cb_enable(GtkWidget *button, NetMon *net)
|
|
{
|
|
enable_in_progress = TRUE;
|
|
net->enabled = GTK_TOGGLE_BUTTON(button)->active;
|
|
if (net->force_button)
|
|
{
|
|
if (net->enabled)
|
|
gtk_widget_set_sensitive(net->force_button, TRUE);
|
|
else
|
|
{
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(net->force_button),
|
|
FALSE);
|
|
gtk_widget_set_sensitive(net->force_button, FALSE);
|
|
net->force_up = FALSE;
|
|
}
|
|
}
|
|
gtk_widget_set_sensitive(net->alert_button, net->enabled);
|
|
if (net == net_timed && !net->enabled && timer_iface_combo)
|
|
gtk_entry_set_text(
|
|
GTK_ENTRY(GTK_COMBO(timer_iface_combo)->entry), "none");
|
|
else
|
|
sync_chart(net);
|
|
enable_in_progress = FALSE;
|
|
net_spacer_visibility();
|
|
}
|
|
|
|
static void
|
|
cb_launch_entry(GtkWidget *widget, NetMon *net)
|
|
{
|
|
if (net->chart)
|
|
gkrellm_apply_launcher(&net->launch_entry, &net->tooltip_entry,
|
|
net->chart->panel, &net->launch, gkrellm_launch_button_cb);
|
|
}
|
|
|
|
static void
|
|
cb_text_format(GtkWidget *widget, gpointer data)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
gchar *s;
|
|
|
|
s = gkrellm_gtk_entry_get_text(&(GTK_COMBO(text_format_combo)->entry));
|
|
gkrellm_locale_dup_string(&text_format, s, &text_format_locale);
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
net->new_text_format = TRUE;
|
|
refresh_net_chart(net);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cb_label_entry(GtkWidget *widget, NetMon *net)
|
|
{
|
|
gkrellm_dup_string(&net->label,
|
|
gkrellm_gtk_entry_get_text(&net->label_entry));
|
|
refresh_net_chart(net);
|
|
}
|
|
|
|
static void
|
|
cb_set_alert(GtkWidget *button, NetMon *net)
|
|
{
|
|
|
|
#if 0
|
|
GtkTreeModel *model;
|
|
GtkTreePath *path;
|
|
GtkTreeIter iter;
|
|
NetMon *net;
|
|
|
|
if (!row_reference)
|
|
return;
|
|
model = gtk_tree_view_get_model(treeview);
|
|
path = gtk_tree_row_reference_get_path(row_reference);
|
|
gtk_tree_model_get_iter(model, &iter, path);
|
|
gtk_tree_model_get(model, &iter, NETMON_COLUMN, &net, -1);
|
|
#endif
|
|
|
|
if (!net->alert)
|
|
create_alert(net);
|
|
gkrellm_alert_config_window(&net->alert);
|
|
|
|
#if 0
|
|
gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
|
|
ALERT_COLUMN, net->alert, -1);
|
|
#endif
|
|
}
|
|
|
|
/* Callback for a created or destroyed alert. Find the sensor in the model
|
|
| and set the IMAGE_COLUMN.
|
|
*/
|
|
static void
|
|
cb_alert_config(GkrellmAlert *ap, NetMon *net)
|
|
{
|
|
#if 0
|
|
GtkTreeModel *model;
|
|
GtkTreeIter iter;
|
|
NetMon *net_test;
|
|
GdkPixbuf *pixbuf;
|
|
gchar node[2];
|
|
gint i;
|
|
|
|
if (!gkrellm_config_window_shown())
|
|
return;
|
|
model = gtk_tree_view_get_model(treeview);
|
|
pixbuf = ap->activated ? gkrellm_alert_pixbuf() : NULL;
|
|
for (i = 0; i < 2; ++i)
|
|
{
|
|
node[0] = '0' + i; /* toplevel Primary or Secondary node */
|
|
node[1] = '\0';
|
|
if (get_child_iter(model, node, &iter))
|
|
do
|
|
{
|
|
gtk_tree_model_get(model, &iter, NETMON_COLUMN, &net_test, -1);
|
|
if (net != net_test)
|
|
continue;
|
|
gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
|
|
IMAGE_COLUMN, pixbuf, -1);
|
|
return;
|
|
}
|
|
while (gtk_tree_model_iter_next(model, &iter));
|
|
}
|
|
#endif
|
|
net->alert_uses_rx =
|
|
GTK_TOGGLE_BUTTON(net->alert_config_rx_button)->active;
|
|
net->alert_uses_tx =
|
|
GTK_TOGGLE_BUTTON(net->alert_config_tx_button)->active;
|
|
}
|
|
|
|
static void
|
|
cb_alert_config_button(GtkWidget *button, NetMon *net)
|
|
{
|
|
gboolean read, write;
|
|
|
|
read = GTK_TOGGLE_BUTTON(net->alert_config_rx_button)->active;
|
|
write = GTK_TOGGLE_BUTTON(net->alert_config_tx_button)->active;
|
|
if (!read && !write)
|
|
{
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(net->alert_config_rx_button), TRUE);
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(net->alert_config_tx_button), TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cb_alert_config_create(GkrellmAlert *ap, GtkWidget *vbox, NetMon *net)
|
|
{
|
|
gkrellm_gtk_check_button_connected(vbox, &net->alert_config_rx_button,
|
|
net->alert_uses_rx, FALSE, FALSE, 2,
|
|
cb_alert_config_button, net, _("rx bytes"));
|
|
gkrellm_gtk_check_button_connected(vbox, &net->alert_config_tx_button,
|
|
net->alert_uses_tx, FALSE, FALSE, 2,
|
|
cb_alert_config_button, net, _("tx bytes"));
|
|
}
|
|
|
|
|
|
static void
|
|
cb_timer_enable(GtkWidget *button, gpointer data)
|
|
{
|
|
gkrellm_panel_enable_visibility(timer_panel,
|
|
GTK_TOGGLE_BUTTON(enable_net_timer_button)->active,
|
|
&timer_button_enabled);
|
|
gtk_widget_set_sensitive(net_timer_seconds_button, timer_button_enabled);
|
|
if (timer_iface_combo)
|
|
{
|
|
if (!timer_button_enabled)
|
|
gtk_entry_set_text(
|
|
GTK_ENTRY(GTK_COMBO(timer_iface_combo)->entry), "none");
|
|
gtk_widget_set_sensitive(timer_iface_combo, timer_button_enabled);
|
|
}
|
|
net_timer_visibility();
|
|
}
|
|
|
|
static void
|
|
cb_timer_seconds(GtkWidget *button, gpointer data)
|
|
{
|
|
timer_seconds = GTK_TOGGLE_BUTTON(button)->active;
|
|
gkrellm_panel_destroy(timer_panel);
|
|
create_net_timer(timer_vbox, TRUE);
|
|
draw_timer(timer_panel, last_time , 1);
|
|
}
|
|
|
|
static void
|
|
cb_timer_iface(GtkWidget *widget, gpointer data)
|
|
{
|
|
gchar *s;
|
|
|
|
s = gkrellm_gtk_entry_get_text(&(GTK_COMBO(timer_iface_combo)->entry));
|
|
if (*s == '\0')
|
|
s = "none";
|
|
if (gkrellm_dup_string(&timer_button_iface, s))
|
|
{
|
|
/* A new timer_button_iface, so destroy old one. If the old one
|
|
| is up or forced up, a new chart for it needs to be created in
|
|
| another vbox, so fake an up_event.
|
|
*/
|
|
if (net_timed)
|
|
{
|
|
destroy_chart(net_timed);
|
|
if ( net_timed->enabled
|
|
&& (net_timed->up || net_timed->force_up)
|
|
)
|
|
net_timed->up_event = TRUE;
|
|
}
|
|
create_timed_monitor();
|
|
if (net_timed)
|
|
gtk_toggle_button_set_active(
|
|
GTK_TOGGLE_BUTTON(net_timed->enable_button), TRUE);
|
|
draw_timer(timer_panel, (int) (time(0) - net_timer0), 1);
|
|
gkrellm_draw_panel_layers(timer_panel);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cb_pon_entry(GtkWidget *widget, gpointer data)
|
|
{
|
|
gchar *s;
|
|
|
|
s = gkrellm_gtk_entry_get_text(&pon_entry);
|
|
gkrellm_dup_string(&timer_on_command, s);
|
|
}
|
|
|
|
static void
|
|
cb_poff_entry(GtkWidget *widget, gpointer data)
|
|
{
|
|
gchar *s;
|
|
|
|
s = gkrellm_gtk_entry_get_text(&poff_entry);
|
|
gkrellm_dup_string(&timer_off_command, s);
|
|
}
|
|
|
|
static void
|
|
cb_reset_mday(GtkWidget *widget, GtkSpinButton *spin)
|
|
{
|
|
GList *list;
|
|
NetMon *net;
|
|
NetStat *ns;
|
|
struct tm *tm;
|
|
gint year, month, mday, month_delta;
|
|
|
|
reset_mday = gtk_spin_button_get_value_as_int(spin);
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
net->month_stats[0].rx = net->month_stats[0].tx = 0.0;
|
|
net->month_stats[0].connect_time = 0;
|
|
tm = gkrellm_get_current_time();
|
|
net_stat_set_date_string(&net->month_stats[0], MONTH_STAT, tm);
|
|
|
|
for (ns = &net->day_stats[0]; ns < &net->day_stats[N_DAY_STATS]; ++ns)
|
|
{
|
|
if (sscanf(ns->date, "%d-%d-%d", &year, &month, &mday) != 3)
|
|
continue;
|
|
year -= 1900; /* Adjust to struct tm ranges */
|
|
month -= 1;
|
|
month_delta = (tm->tm_year * 12 + tm->tm_mon)
|
|
- (year * 12 + month);
|
|
if ( ( tm->tm_mday < reset_mday
|
|
&& ( (month_delta > 1)
|
|
|| (month_delta == 1 && mday < reset_mday)
|
|
)
|
|
)
|
|
|| ( tm->tm_mday >= reset_mday
|
|
&& ( (month_delta > 0)
|
|
|| (month_delta == 0 && mday < reset_mday)
|
|
)
|
|
)
|
|
)
|
|
continue;
|
|
|
|
net->month_stats[0].rx += ns->rx;
|
|
net->month_stats[0].tx += ns->tx;
|
|
net->month_stats[0].connect_time += ns->connect_time;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if !defined(WIN32)
|
|
static gchar *net_info_text0[] =
|
|
{
|
|
N_("<h>Timer Button\n"),
|
|
N_("\tThe timer button may be used as a stand alone timer with start and\n"
|
|
"\tstop commands, but it is usually linked to a dial up net interface\n"
|
|
"\twhere the commands can control the interface and different timer\n"
|
|
"\tbutton colors can show connect states:\n"),
|
|
"\n",
|
|
#if defined(__FreeBSD__)
|
|
"<b>\ttun: ",
|
|
#else
|
|
"<b>\tppp: ",
|
|
#endif
|
|
N_("Standby state is while the modem phone line is locked while\n"
|
|
"\tppp is connecting, and the on state is the ppp link connected.\n"
|
|
"\tThe phone line lock is determined by the existence of the modem\n"
|
|
"\tlock file /var/lock/LCK..modem. If your pppd setup does not\n"
|
|
"\tuse /dev/modem, then you can configure an alternative with:\n"),
|
|
N_("<i>\t\tln -s /var/lock/LCK..ttySx ~/.gkrellm2/LCK..modem\n"),
|
|
N_("\twhere ttySx is the tty device your modem uses. The ppp on\n"
|
|
"\tstate is detected by the existence of /var/run/pppX.pid and\n"
|
|
"\tthe time stamp of this file is the base for the on line time.\n"),
|
|
#if defined(__linux__)
|
|
"\n",
|
|
"<b>\tippp: ",
|
|
N_("The timer button standby state is not applicable to isdn\n"
|
|
"\tinterfaces that are always routed. The on state is isdn on line\n"
|
|
"\twhile the ippp interface is routed. The on line timer is reset\n"
|
|
"\twhen the isdn interface transitions from a hangup to an on line\n"
|
|
"\tstate\n"),
|
|
#endif
|
|
"\n"
|
|
};
|
|
#endif
|
|
|
|
static gchar *net_info_text1[] =
|
|
{
|
|
N_("<h>Chart Labels\n"),
|
|
N_("Substitution variables for the format string for chart labels:\n"),
|
|
N_("\t$M maximum chart value\n"),
|
|
N_("\t$T receive + transmit bytes\n"),
|
|
N_("\t$r receive bytes\n"),
|
|
N_("\t$t transmit bytes\n"),
|
|
N_("\t$O cumulative receive + transmit bytes\n"),
|
|
N_("\t$i cumulative receive bytes\n"),
|
|
N_("\t$o cumulative transmit bytes\n"),
|
|
N_("\t$L the optional chart label\n"),
|
|
N_("\t$I the net interface name\n"),
|
|
"\n",
|
|
N_("The cumulative variables may have a 'd', 'w', or 'm' qualifier for\n"
|
|
"daily, weekly, or monthly totals. For example: $Ow for a\n"
|
|
"cumulative weekly receive + transmit bytes.\n"),
|
|
"\n",
|
|
N_("Substitution variables may be used in alert commands.\n")
|
|
};
|
|
|
|
static void
|
|
create_net_tab(GtkWidget *tab_vbox)
|
|
{
|
|
GtkWidget *tabs;
|
|
GtkWidget *table;
|
|
GtkWidget *vbox, *vbox1;
|
|
GtkWidget *hbox;
|
|
GtkWidget *label;
|
|
GtkWidget *text;
|
|
GList *list, *tlist;
|
|
NetMon *net;
|
|
TimerType *tt;
|
|
gchar buf[256];
|
|
gint i;
|
|
|
|
tabs = gtk_notebook_new();
|
|
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
|
|
gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
|
|
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Timer Button"));
|
|
|
|
if (timer_button_type != TIMER_TYPE_SERVER) /* enabled by gkrellmd.conf? */
|
|
gkrellm_gtk_check_button_connected(vbox, &enable_net_timer_button,
|
|
timer_button_enabled, FALSE, FALSE, 10,
|
|
cb_timer_enable, NULL,
|
|
_("Enable timer button"));
|
|
|
|
gkrellm_gtk_check_button_connected(vbox, &net_timer_seconds_button,
|
|
timer_seconds, FALSE, FALSE, 0,
|
|
cb_timer_seconds, NULL,
|
|
_("Show seconds"));
|
|
hbox = gtk_hbox_new (FALSE, 3);
|
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 50);
|
|
|
|
if (!_GK.client_mode)
|
|
{
|
|
timer_iface_combo = gtk_combo_new();
|
|
gtk_box_pack_start(GTK_BOX(hbox), timer_iface_combo, FALSE, TRUE, 0);
|
|
list = NULL;
|
|
list = g_list_append(list, _("none"));
|
|
for (tlist = timer_defaults_list; tlist; tlist = tlist->next)
|
|
{
|
|
tt = (TimerType *) tlist->data;
|
|
list = g_list_append(list, tt->name);
|
|
}
|
|
gtk_combo_set_popdown_strings(GTK_COMBO(timer_iface_combo), list);
|
|
gtk_combo_set_case_sensitive(GTK_COMBO(timer_iface_combo), TRUE);
|
|
g_list_free(list);
|
|
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(timer_iface_combo)->entry),
|
|
timer_button_iface);
|
|
g_signal_connect(G_OBJECT(GTK_COMBO(timer_iface_combo)->entry),
|
|
"changed", G_CALLBACK(cb_timer_iface), NULL);
|
|
|
|
label = gtk_label_new(_("Interface to link to the timer button"));
|
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
|
|
}
|
|
vbox = gkrellm_gtk_framed_vbox_end(vbox, NULL, 4, FALSE, 0, 2);
|
|
hbox = gtk_hbox_new (FALSE, 3);
|
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
|
|
|
|
vbox1 = gtk_vbox_new(FALSE, 3);
|
|
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 3);
|
|
gtk_container_add(GTK_CONTAINER(hbox), vbox1);
|
|
label = gtk_label_new(_("Start Command"));
|
|
gtk_box_pack_start(GTK_BOX (vbox1), label, FALSE, TRUE, 0);
|
|
pon_entry = gtk_entry_new();
|
|
gtk_box_pack_start(GTK_BOX (vbox1), pon_entry, FALSE, TRUE, 0);
|
|
gtk_entry_set_text(GTK_ENTRY(pon_entry), timer_on_command);
|
|
g_signal_connect(G_OBJECT(pon_entry),
|
|
"changed", G_CALLBACK(cb_pon_entry), NULL);
|
|
|
|
vbox1 = gtk_vbox_new(FALSE, 3);
|
|
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 3);
|
|
gtk_container_add(GTK_CONTAINER(hbox), vbox1);
|
|
label = gtk_label_new(_("Stop Command"));
|
|
gtk_box_pack_start(GTK_BOX (vbox1), label, FALSE, TRUE, 0);
|
|
poff_entry = gtk_entry_new();
|
|
gtk_box_pack_start(GTK_BOX (vbox1), poff_entry, FALSE, TRUE, 0);
|
|
gtk_entry_set_text(GTK_ENTRY(poff_entry), timer_off_command);
|
|
g_signal_connect(G_OBJECT(poff_entry),
|
|
"changed", G_CALLBACK(cb_poff_entry), NULL);
|
|
|
|
for (list = net_mon_list; list; list = list->next)
|
|
{
|
|
net = (NetMon *) list->data;
|
|
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, net->name);
|
|
|
|
snprintf(buf, sizeof(buf), _("Enable %s"), net->name);
|
|
hbox = gtk_hbox_new (FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
|
|
gkrellm_gtk_check_button_connected(hbox,
|
|
&net->enable_button, net->enabled,
|
|
FALSE, FALSE, 0,
|
|
cb_enable, net, buf);
|
|
gkrellm_gtk_alert_button(hbox, &net->alert_button, FALSE, FALSE, 4,
|
|
FALSE, cb_set_alert, net);
|
|
gtk_widget_set_sensitive(net->alert_button, net->enabled);
|
|
|
|
|
|
if (net_config_use_routed)
|
|
{
|
|
gkrellm_gtk_check_button_connected(vbox, &net->force_button,
|
|
net->enabled ? net->force_up : FALSE, FALSE, FALSE, 0,
|
|
cb_force, net,
|
|
_("Force chart to be always shown even if interface is not routed."));
|
|
if (!net->enabled)
|
|
gtk_widget_set_sensitive(net->force_button, FALSE);
|
|
}
|
|
|
|
hbox = gtk_hbox_new (FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 12);
|
|
|
|
net->label_entry = gtk_entry_new();
|
|
gtk_entry_set_max_length(GTK_ENTRY(net->label_entry), 16);
|
|
gtk_widget_set_size_request(net->label_entry, 70, -1);
|
|
gtk_entry_set_text(GTK_ENTRY(net->label_entry), net->label);
|
|
gtk_box_pack_start (GTK_BOX (hbox), net->label_entry, FALSE, TRUE, 2);
|
|
label = gtk_label_new(_("Optional label for this interface."));
|
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
|
|
g_signal_connect(G_OBJECT(net->label_entry), "changed",
|
|
G_CALLBACK(cb_label_entry), net);
|
|
|
|
vbox = gkrellm_gtk_category_vbox(vbox,
|
|
_("Launch Commands"),
|
|
4, 0, TRUE);
|
|
table = gkrellm_gtk_launcher_table_new(vbox, 1);
|
|
gkrellm_gtk_config_launcher(table, 0, &net->launch_entry,
|
|
&net->tooltip_entry, net->name, &net->launch);
|
|
g_signal_connect(G_OBJECT(net->launch_entry), "changed",
|
|
G_CALLBACK(cb_launch_entry), net);
|
|
g_signal_connect(G_OBJECT(net->tooltip_entry), "changed",
|
|
G_CALLBACK(cb_launch_entry), net);
|
|
}
|
|
|
|
/* -- Setup tab */
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Setup"));
|
|
|
|
vbox1 = gkrellm_gtk_category_vbox(vbox,
|
|
_("Format String for Chart Labels"),
|
|
4, 0, TRUE);
|
|
text_format_combo = gtk_combo_new();
|
|
gtk_widget_set_size_request (GTK_WIDGET(text_format_combo), 300, -1);
|
|
gtk_box_pack_start(GTK_BOX(vbox1), text_format_combo, FALSE, FALSE, 2);
|
|
list = NULL;
|
|
list = g_list_append(list, text_format);
|
|
list = g_list_append(list, DEFAULT_TEXT_FORMAT);
|
|
list = g_list_append(list, "\\c\\f$M\\n$T\\b\\c\\f$L");
|
|
list = g_list_append(list,
|
|
_("\\f\\ww\\c\\f$M\\n\\f\\at\\.$t\\n\\f\\ar\\.$r\\b\\c\\f$L"));
|
|
list = g_list_append(list,
|
|
_("\\f\\ww\\c\\f$M\\n\\f\\at\\.$o\\n\\f\\ar\\.$i\\b\\c\\f$L"));
|
|
list = g_list_append(list,
|
|
_("\\f\\ww\\c\\f$M\\D2\\f\\ar\\.$r\\D1\\f\\at\\.$t\\b\\c\\f$L"));
|
|
gtk_combo_set_popdown_strings(GTK_COMBO(text_format_combo), list);
|
|
gtk_combo_set_case_sensitive(GTK_COMBO(text_format_combo), TRUE);
|
|
g_list_free(list);
|
|
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(text_format_combo)->entry),
|
|
text_format);
|
|
g_signal_connect(G_OBJECT(GTK_COMBO(text_format_combo)->entry), "changed",
|
|
G_CALLBACK(cb_text_format), NULL);
|
|
|
|
gkrellm_gtk_spin_button(vbox, NULL, (gfloat) reset_mday,
|
|
1.0, 31.0, 1.0, 1.0, 0, 55,
|
|
cb_reset_mday, NULL, FALSE,
|
|
_("Start day for cumulative monthly transmit and receive bytes"));
|
|
|
|
/* --Info tab */
|
|
vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Info"));
|
|
text = gkrellm_gtk_scrolled_text_view(vbox, NULL,
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
#if !defined(WIN32)
|
|
if (!_GK.client_mode)
|
|
for (i = 0; i < sizeof(net_info_text0)/sizeof(gchar *); ++i)
|
|
gkrellm_gtk_text_view_append(text, _(net_info_text0[i]));
|
|
#endif
|
|
for (i = 0; i < sizeof(net_info_text1)/sizeof(gchar *); ++i)
|
|
gkrellm_gtk_text_view_append(text, _(net_info_text1[i]));
|
|
}
|
|
|
|
|
|
|
|
static GkrellmMonitor monitor_net =
|
|
{
|
|
N_("Net"), /* Name, for config tab. */
|
|
MON_NET, /* Id, 0 if a plugin */
|
|
create_net, /* The create function */
|
|
update_net, /* The update function */
|
|
create_net_tab, /* The config tab create function */
|
|
NULL, /* Instant apply */
|
|
|
|
save_net_config, /* Save user conifg */
|
|
load_net_config, /* Load user config */
|
|
NET_CONFIG_KEYWORD, /* config keyword */
|
|
|
|
NULL, /* Undef 2 */
|
|
NULL, /* Undef 1 */
|
|
NULL, /* Undef 0 */
|
|
|
|
0, /* insert_before_id - place plugin before this mon */
|
|
|
|
NULL, /* Handle if a plugin, filled in by GKrellM */
|
|
NULL /* path if a plugin, filled in by GKrellM */
|
|
};
|
|
|
|
GkrellmMonitor *
|
|
gkrellm_init_net_monitor(void)
|
|
{
|
|
TimerType *tt;
|
|
|
|
if (!setup_net_interface())
|
|
return NULL;
|
|
time(&net_timer0);
|
|
if (timer_defaults_list)
|
|
{
|
|
tt = (TimerType *) timer_defaults_list->data;
|
|
timer_button_iface = g_strdup(tt->name);
|
|
timer_button_type = tt->type;
|
|
}
|
|
else
|
|
{
|
|
timer_button_iface = g_strdup("none");
|
|
}
|
|
if (!_GK.client_mode)
|
|
timer_button_enabled = TRUE;
|
|
else
|
|
timer_button_enabled = (timer_button_type == TIMER_TYPE_SERVER);
|
|
|
|
timer_seconds = TRUE;
|
|
timer_on_command = g_strdup("");
|
|
timer_off_command = g_strdup("");
|
|
gkrellm_locale_dup_string(&text_format, DEFAULT_TEXT_FORMAT,
|
|
&text_format_locale);
|
|
|
|
net_stats_window_height = 200;
|
|
|
|
monitor_net.name = _(monitor_net.name);
|
|
net_style_id = gkrellm_add_chart_style(&monitor_net, NET_STYLE_NAME);
|
|
mon_net = &monitor_net;
|
|
return &monitor_net;
|
|
}
|
|
|
|
|
|
static GkrellmMonitor monitor_timer =
|
|
{
|
|
N_("Net Timer"), /* Name, for config tab. */
|
|
MON_TIMER, /* Id, 0 if a plugin */
|
|
create_timer, /* The create function */
|
|
NULL, /* The update function */
|
|
NULL, /* The config tab create function */
|
|
NULL, /* Apply the config function */
|
|
|
|
NULL, /* Save user conifg */
|
|
NULL, /* Load user config */
|
|
NULL, /* config keyword */
|
|
|
|
NULL, /* Undef 2 */
|
|
NULL, /* Undef 1 */
|
|
NULL, /* Undef 0 */
|
|
|
|
0, /* insert_before_id - place plugin before this mon */
|
|
|
|
NULL, /* Handle if a plugin, filled in by GKrellM */
|
|
NULL /* path if a plugin, filled in by GKrellM */
|
|
};
|
|
|
|
GkrellmMonitor *
|
|
gkrellm_init_timer_monitor(void)
|
|
{
|
|
if (!mon_net)
|
|
return NULL;
|
|
monitor_timer.name = _(monitor_timer.name);
|
|
timer_style_id = gkrellm_add_meter_style(&monitor_timer, TIMER_STYLE_NAME);
|
|
mon_timer = &monitor_timer;
|
|
net_data_dir = gkrellm_make_data_file_name("net", NULL);
|
|
reset_mday = 1;
|
|
return &monitor_timer;
|
|
}
|
|
|