📄 proc.c
字号:
/* GKrellM| Copyright (C) 1999-2006 Bill Wilson|| Author: Bill Wilson billw@gkrellm.net| Latest versions might be found at: http://gkrellm.net|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that license as published by the Free Software Foundation; either| version 2 of the License, or (at your option) any later version.|| This program 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. Version 2 is in the| COPYRIGHT file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "gkrellm.h"#include "gkrellm-private.h"#include "gkrellm-sysdeps.h"#include <math.h>typedef struct { gchar *panel_label; GtkWidget *vbox; GkrellmChart *chart; GkrellmChartdata *forks_cd; GkrellmChartconfig *chart_config; gint enabled; gboolean extra_info; gint save_label_position; gpointer sensor_temp, sensor_fan; GkrellmDecal *sensor_decal, *fan_decal; gint n_users; gint n_processes; gint n_running; gulong n_forks; gfloat fload; } ProcMon;ProcMon proc;void (*read_proc_data)();void (*read_user_data)();GkrellmAlert *load_alert, *processes_alert, *users_alert;static gbooleansetup_proc_interface(void) { if (!read_proc_data && !_GK.client_mode && gkrellm_sys_proc_init()) { read_proc_data = gkrellm_sys_proc_read_data; read_user_data = gkrellm_sys_proc_read_users; } return read_proc_data ? TRUE : FALSE; }voidgkrellm_proc_client_divert(void (*read_proc_func)(), void (*read_users_func)()) { read_proc_data = read_proc_func; read_user_data = read_users_func; }voidgkrellm_proc_assign_data(gint n_processes, gint n_running, gulong n_forks, gfloat load) { proc.n_processes = n_processes; proc.n_running = n_running; proc.n_forks = n_forks; proc.fload = load; }voidgkrellm_proc_assign_users(gint n_users) { proc.n_users = n_users; }/* ======================================================================== */ /* GkrellmCharts are integer only and load is a small real, so scale all load | reading by 100. */#define LOAD_SCALING 100.0static GkrellmMonitor *mon_proc;static GkrellmLauncher proc_launch;static gint style_id;static gboolean show_temperature, show_fan;static gboolean sensor_separate_mode;static gint fork_scaling = 1;static gchar *text_format, *text_format_locale;static gboolean new_text_format = TRUE;static voidformat_proc_data(ProcMon *p, gchar *src_string, gchar *buf, gint size) { GkrellmChart *cp; gchar c, *s; gint len, value; if (!buf || size < 1) return; --size; *buf = '\0'; if (!src_string) return; cp = p->chart; for (s = src_string; *s != '\0' && size > 0; ++s) { len = 1; if (*s == '$' && *(s + 1) != '\0') { value = -1; if ((c = *(s + 1)) == 'L') len = snprintf(buf, size, "%.1f", (gfloat) gkrellm_get_chart_scalemax(cp) / LOAD_SCALING); else if (c == 'F' && fork_scaling > 0) len = snprintf(buf, size, "%d", gkrellm_get_chart_scalemax(cp) / fork_scaling); else if (c == 'H') len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name()); else if (c == 'l') len = snprintf(buf, size, "%.1f", p->fload); else if (c == 'p') value = p->n_processes; else if (c == 'u') value = p->n_users; else if (c == 'f') value = gkrellm_get_current_chartdata(p->forks_cd) / fork_scaling; if (value >= 0) len = snprintf(buf, size, "%d", value); ++s; } else *buf = *s; size -= len; buf += len; } *buf = '\0'; }static voiddraw_proc_extra(void) { gchar buf[128]; if (!proc.chart || !proc.extra_info) return; format_proc_data(&proc, text_format_locale, buf, sizeof(buf)); if (!new_text_format) gkrellm_chart_reuse_text_format(proc.chart); new_text_format = FALSE; gkrellm_draw_chart_text(proc.chart, style_id, buf); }static voidcb_command_process(GkrellmAlert *alert, gchar *src, gchar *dst, gint len, gpointer data) { format_proc_data(&proc, src, dst, len); }static voidrefresh_proc_chart(GkrellmChart *cp) { if (proc.enabled) { gkrellm_draw_chartdata(cp); if (proc.extra_info) draw_proc_extra(); gkrellm_draw_chart_to_screen(cp); } }static voiddraw_sensor_decals(void) { GkrellmPanel *p = proc.chart->panel; gchar units; gfloat t, f; gint toggle; if (sensor_separate_mode && show_temperature && show_fan) { gkrellm_sensor_read_temperature(proc.sensor_temp, &t, &units); gkrellm_sensor_draw_temperature_decal(p, proc.sensor_decal, t, units); gkrellm_sensor_read_fan(proc.sensor_fan, &f); gkrellm_sensor_draw_fan_decal(p, proc.fan_decal, f); } else { toggle = _GK.time_now & 2; if (show_fan && (toggle || !show_temperature)) { gkrellm_sensor_read_fan(proc.sensor_fan, &f); gkrellm_sensor_draw_fan_decal(p, proc.sensor_decal, f); } else if (show_temperature && (!toggle || !show_fan) ) { gkrellm_sensor_read_temperature(proc.sensor_temp, &t, &units); gkrellm_sensor_draw_temperature_decal(p, proc.sensor_decal, t, units); } } }voidgkrellm_proc_draw_sensors(gpointer sr) { if (sr && sr != proc.sensor_temp && sr != proc.sensor_fan) return; if (proc.enabled) draw_sensor_decals(); }static voidupdate_proc(void) { GkrellmChart *cp; GkrellmPanel *p; gint load; if (!proc.enabled) return; (*read_proc_data)(); if (GK.five_second_tick) { (*read_user_data)(); gkrellm_check_alert(users_alert, proc.n_users); } cp = proc.chart; p = cp->panel; gkrellm_update_krell(p, KRELL(p), proc.n_forks); gkrellm_draw_panel_layers(p); if (GK.second_tick) { /* Scale load since it is a small real and charts are integer only. | Scale the forks number by fork_scaling. See setup_proc_scaling(). */ load = (int) (LOAD_SCALING * proc.fload); gkrellm_store_chartdata(cp, 0, load, fork_scaling * proc.n_forks); refresh_proc_chart(cp); gkrellm_check_alert(load_alert, proc.fload); gkrellm_check_alert(processes_alert, proc.n_processes); gkrellm_panel_label_on_top_of_decals(p, gkrellm_alert_decal_visible(load_alert) || gkrellm_alert_decal_visible(users_alert) || gkrellm_alert_decal_visible(processes_alert)); } if ( (GK.two_second_tick && !sensor_separate_mode) || (GK.five_second_tick && sensor_separate_mode) ) draw_sensor_decals(); }static gintproc_expose_event(GtkWidget *widget, GdkEventExpose *ev) { GkrellmChart *cp = proc.chart; GdkPixmap *pixmap = NULL; if (cp) { if (widget == cp->drawing_area) pixmap = cp->pixmap; else if (widget == cp->panel->drawing_area) pixmap = cp->panel->pixmap; } 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 gintcb_proc_extra(GtkWidget *widget, GdkEventButton *ev) { if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) { proc.extra_info = !proc.extra_info; gkrellm_config_modified(); refresh_proc_chart(proc.chart); } else if ( ev->button == 3 || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) ) gkrellm_chartconfig_window_create(proc.chart); return FALSE; }static voidsetup_proc_scaling(void) { GkrellmChart *cp = proc.chart; gint grids, res, new_fork_scaling; if (!cp) return; grids = gkrellm_get_chartconfig_fixed_grids(cp->config); if (!grids) grids = FULL_SCALE_GRIDS; res = gkrellm_get_chartconfig_grid_resolution(cp->config); /* Since grid_resolution is set for load, set krell_full_scale explicitely | to get what I want, which is 10 forks full scale. | When res or number of grids is changed, scale all fork data to keep a | fixed 50 forks/sec max on the chart. */ KRELL(cp->panel)->full_scale = 10; new_fork_scaling = grids * res / 50; if (new_fork_scaling < 1) /* shouldn't happen... */ new_fork_scaling = 1; /* If load grid_resolution changed, scale all fork data to keep the | constant 50 forks/sec. */ if (fork_scaling != new_fork_scaling) { /* When called as a callback a chart refresh will follow, but I'll | need a rescale here. */ gkrellm_scale_chartdata(proc.forks_cd, new_fork_scaling, fork_scaling); gkrellm_rescale_chart(proc.chart); } fork_scaling = new_fork_scaling; }static voiddestroy_proc_monitor(void) { GkrellmChart *cp = proc.chart; if (proc_launch.button) gkrellm_destroy_button(proc_launch.button); proc_launch.button = NULL; proc_launch.tooltip = NULL; gkrellm_chart_destroy(cp); proc.chart = NULL; proc.enabled = FALSE; }static voidcb_mb_temp_alert_trigger(GkrellmAlert *alert, ProcMon *proc) { GkrellmAlertdecal *ad; GkrellmDecal *d; if (alert && proc && proc->chart) { ad = &alert->ad; d = proc->sensor_decal; if (d) { ad->x = d->x - 1; ad->y = d->y - 1; ad->w = d->w + 2; ad->h = d->h + 2; gkrellm_render_default_alert_decal(alert); } alert->panel = proc->chart->panel; } }static voidcb_mb_fan_alert_trigger(GkrellmAlert *alert, ProcMon *proc) { GkrellmAlertdecal *ad; GkrellmDecal *d; if (alert && proc && proc->chart) { ad = &alert->ad; if (sensor_separate_mode) d = proc->fan_decal; else d = proc->sensor_decal; if (d) { ad->x = d->x - 1; ad->y = d->y - 1; ad->w = d->w + 2; ad->h = d->h + 2; gkrellm_render_default_alert_decal(alert); } alert->panel = proc->chart->panel; } } /* Next routine is same as in cpu.c - perhaps should make into one?*/ /* How to decide when to make the sensor_decal and fan_decal visible. | The sensor_decal can show temp values, fan values, or alternating | temp/fan values. The fan_decal only shows fan values when non | alternating mode is selected. The sensors are mapped in sensors.c | | Sensor and fan decal display truth table: | |-----decals visible----||--sensors mapped--| separate | | |sensor_decal fan_decal|| temp fan | mode | | |-----------------------||--------------------------------| | | 0 0 || 0 0 0 | | | 1 0 || 1 0 0 | | | 1 0 || 0 1 0 | | | 1 0 || 1 1 0 | | | 0 0 || 0 0 1 | | | 1 0 || 1 0 1 | | | 1 0 || 0 1 1 | | | 1 1 || 1 1 1 | | |---------------------------------------------------------- */static gbooleanadjust_sensors_display(gint force) { GkrellmPanel *p; GkrellmDecal *ds, *df; GkrellmAlert *alert; gint position = 0; ds = proc.sensor_decal; df = proc.fan_decal; if (!ds || !df) return FALSE; /* The test for state change is decal state vs success at reading | a temperature. */ p = proc.chart->panel; show_temperature = show_fan = FALSE; if (!_GK.demo) { gkrellm_sensor_alert_connect(proc.sensor_temp, cb_mb_temp_alert_trigger, &proc); gkrellm_sensor_alert_connect(proc.sensor_fan, cb_mb_fan_alert_trigger, &proc); } /* If a fan alert is triggered, turn it off in case fan decal being used | is changed. The alert will just retrigger at next fan update. */ alert = gkrellm_sensor_alert(proc.sensor_fan); gkrellm_reset_alert_soft(alert); if (proc.sensor_temp || _GK.demo) show_temperature = TRUE; if (proc.sensor_fan || _GK.demo) show_fan = TRUE; if (show_temperature || show_fan) { if (! gkrellm_is_decal_visible(ds) || force) gkrellm_make_decal_visible(p, ds); position = 0; } else { if (gkrellm_is_decal_visible(ds) || force) gkrellm_make_decal_invisible(p, ds); position = proc.save_label_position; } if (show_fan && show_temperature && sensor_separate_mode) { if (! gkrellm_is_decal_visible(df) || force) gkrellm_make_decal_visible(p, df); position = -1; } else { if (gkrellm_is_decal_visible(df) || force) gkrellm_make_decal_invisible(p, df); } if (position != p->label->position || force) { if (proc.save_label_position >= 0) /* Reassign position only if the */ p->label->position = position; /* original label was visible. */ gkrellm_draw_panel_label(p); draw_sensor_decals(); gkrellm_draw_panel_layers(p); } return TRUE; }static gintcb_panel_press(GtkWidget *widget, GdkEventButton *ev) { if (ev->button == 3) gkrellm_open_config_window(mon_proc); return FALSE; }static voidcreate_proc_monitor(GtkWidget *vbox, gint first_create) { GkrellmChart *cp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -