📄 net.c
字号:
{ 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 voiddraw_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 gintnet_stats_window_configure_cb(GtkWidget *widget, GdkEventConfigure *ev, gpointer data) { net_stats_window_height = widget->allocation.height; gkrellm_config_modified(); return FALSE; }static voidnet_stats_close_cb(GtkWidget *widget, GtkWidget *stats_window) { gtk_widget_destroy(stats_window); }static voidnet_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 voidnet_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 gintget_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 voidget_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 voidset_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 voidupdate_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 voidstale_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 gintin_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 gintcb_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 gintcb_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 voidtimed_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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -