summaryrefslogtreecommitdiff
path: root/src/charts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts.c')
-rw-r--r--src/charts.c126
1 files changed, 80 insertions, 46 deletions
diff --git a/src/charts.c b/src/charts.c
index c1af1f4..7b80331 100644
--- a/src/charts.c
+++ b/src/charts.c
@@ -105,28 +105,42 @@ typedef struct _vwm_column_t {
/* TODO: make the columns configurable and add more description/toggled state here */
unsigned enabled:1;
vwm_column_type_t type;
- vwm_side_t side;
int width;
} vwm_column_t;
+/* a row-column is a row's instance of a column, to facilitate rows that want to reference a column multiple times,
+ * as well as the multi-row use adding per-proc memory rows will start doing - there will need to be a way to
+ * for instance get the _TREE column into the memory row for continuity purposes (though it will likely need to be
+ * augmented slightly in the sub-row or whatever that becomes) as there won't be any Argv to point at in the memory
+ * row following the CPU row.
+ */
+typedef struct _vwm_row_column_t {
+ vwm_column_t *column;
+ vwm_side_t side;
+} vwm_row_column_t;
+
/* everything needed by the per-window chart's context */
typedef struct _vwm_chart_t {
- vmon_proc_t *proc; /* vmon process monitor handle */
- vcr_t *vcr;
+ vmon_proc_t *proc; /* vmon process monitor handle */
+ vcr_t *vcr;
- int hierarchy_end; /* row where the process hierarchy currently ends */
+ int hierarchy_end; /* row where the process hierarchy currently ends */
/* FIXME TODO: this is redundant with the same things in vcr_t now, dedupe them */
- int visible_width; /* currently visible width of the chart */
- int visible_height; /* currently visible height of the chart */
-
- int snowflakes_cnt; /* count of snowflaked rows (reset to zero to truncate snowflakes display) */
- int gen_last_composed; /* the last composed vmon generation */
- int redraw_needed; /* if a redraw is required (like when the window is resized...) */
- char *name; /* name if provided, included in chart by the \/\/\ */
- vwm_column_t top_columns[CHART_MAX_COLUMNS]; /* "top" columns in the chart (vwm logo, hz) */
- vwm_column_t proc_cpu_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the chart TODO, for now just stowing the widths here */
- vwm_column_t snowflake_cpu_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the snowflaked rows */
+ int visible_width; /* currently visible width of the chart */
+ int visible_height; /* currently visible height of the chart */
+
+ int snowflakes_cnt; /* count of snowflaked rows (reset to zero to truncate snowflakes display) */
+ int gen_last_composed; /* the last composed vmon generation */
+ int redraw_needed; /* if a redraw is required (like when the window is resized...) */
+ char *name; /* name if provided, included in chart by the \/\/\ */
+ vwm_column_t top_columns[CHART_MAX_COLUMNS]; /* "top" columns in the chart (vwm logo, hz) */
+ vwm_column_t proc_cpu_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the chart TODO, for now just stowing the widths here */
+ vwm_column_t snowflake_cpu_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the snowflaked rows */
+
+ vwm_row_column_t top_row_columns[CHART_MAX_COLUMNS]; /* "top" columns in the chart (vwm logo, hz) */
+ vwm_row_column_t proc_cpu_row_columns[CHART_MAX_COLUMNS];
+ vwm_row_column_t snowflake_cpu_row_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the snowflaked rows */
} vwm_chart_t;
/* space we need for every process being monitored */
@@ -591,7 +605,7 @@ needs_tee:
/* draw a proc row according to the columns configured in columns,
* row==0 is treated specially as the heading row
*/
-static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t *columns, int heading, int depth, int row, const vmon_proc_t *proc)
+static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_column_t *row_columns, int heading, int depth, int row, const vmon_proc_t *proc)
{
vmon_sys_stat_t *sys_stat = charts->vmon.stores[VMON_STORE_SYS_STAT];
vmon_proc_stat_t *proc_stat = proc->stores[VMON_STORE_PROC_STAT];
@@ -599,11 +613,12 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
char str[256];
for (int i = 0, left = 0, right = 0; i < CHART_MAX_COLUMNS; i++) {
- vwm_column_t *c = &columns[i];
- vwm_justify_t str_justify = VWM_JUSTIFY_CENTER;
- int str_len = 0, uniform = 1, advance = 1;
+ vwm_row_column_t *rc = &row_columns[i];
+ vwm_column_t *c = rc->column;
+ vwm_justify_t str_justify = VWM_JUSTIFY_CENTER;
+ int str_len = 0, uniform = 1, advance = 1;
- if (!c->enabled)
+ if (!c || !c->enabled)
continue;
/* XXX FIXME: i don't constrain columns using a clip mask or restrained drawing, so they can scribble
@@ -613,7 +628,7 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
* a column's width became too large, the clearing itself can be destructive. This works fine for
* the currently configured columns, but long-term this will have to get fixed properly.
*/
- if (c->side == VWM_SIDE_LEFT)
+ if (rc->side == VWM_SIDE_LEFT)
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, left, c->width + VCR_ROW_HEIGHT / 2);
else
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, chart->visible_width - (c->width + VCR_ROW_HEIGHT / 2 + right), c->width + VCR_ROW_HEIGHT / 2);
@@ -681,7 +696,7 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
if (heading) /* tree markup needs no heading */
break;
- assert(c->side == VWM_SIDE_LEFT); /* XXX: technically SIDE_RIGHT could work, but doesn't currently */
+ assert(rc->side == VWM_SIDE_LEFT); /* XXX: technically SIDE_RIGHT could work, but doesn't currently */
draw_tree_row(charts, chart, left, depth, row, proc, &width);
left += width;
@@ -696,7 +711,7 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
} else {
int width;
- print_argv(charts, chart, left /* FIXME: consider c->side */, row, proc, &width);
+ print_argv(charts, chart, left /* FIXME: consider rc->side */, row, proc, &width);
if (width > c->width) {
c->width = width;
chart->redraw_needed++;
@@ -765,8 +780,8 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
chart->redraw_needed++;
}
- /* get xpos to the left edge of the column WRT c->width and c->side */
- switch (c->side) {
+ /* get xpos to the left edge of the column WRT c->width and rc->side */
+ switch (rc->side) {
case VWM_SIDE_LEFT:
xpos = left;
break;
@@ -801,8 +816,8 @@ static void draw_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_column_t
}
if (advance) {
- left += (c->side == VWM_SIDE_LEFT) * (c->width + VCR_ROW_HEIGHT / 2);
- right += (c->side == VWM_SIDE_RIGHT) * (c->width + VCR_ROW_HEIGHT / 2);
+ left += (rc->side == VWM_SIDE_LEFT) * (c->width + VCR_ROW_HEIGHT / 2);
+ right += (rc->side == VWM_SIDE_RIGHT) * (c->width + VCR_ROW_HEIGHT / 2);
}
}
}
@@ -882,7 +897,7 @@ static void draw_overlay_row(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc
if (!proc->is_new) /* XXX for now always clear the row, this should be capable of being optimized in the future (if the datums driving the text haven't changed...) */
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1);
- draw_columns(charts, chart, chart->proc_cpu_columns, 0 /* heading */, depth, row, proc);
+ draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 0 /* heading */, depth, row, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row);
}
@@ -974,7 +989,7 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_
chart->snowflakes_cnt++;
/* stamp the name (and whatever else we include) into chart.text_picture */
- draw_columns(charts, chart, chart->snowflake_cpu_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc);
+ draw_row_columns(charts, chart, chart->snowflake_cpu_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end);
chart->hierarchy_end--;
@@ -1111,11 +1126,11 @@ static void draw_chart(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_t *pr
if (sample_duration_idx == (charts->this_sample_duration - 1)) {
if (deferred_pass || (!charts->defer_maintenance && (chart->redraw_needed || charts->prev_sampling_interval_secs != charts->sampling_interval_secs))) {
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1);
- draw_columns(charts, chart, chart->top_columns, 1 /* heading */, 0 /* depth */, row, proc);
+ draw_row_columns(charts, chart, chart->top_row_columns, 1 /* heading */, 0 /* depth */, row, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row);
vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 1, -1, -1);
- draw_columns(charts, chart, chart->proc_cpu_columns, 1 /* heading */, 0 /* depth */, row + 2, proc);
+ draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 1 /* heading */, 0 /* depth */, row + 2, proc);
vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 1);
}
@@ -1246,24 +1261,43 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei
}
}
- chart->top_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_VWM, .side = VWM_SIDE_RIGHT };
+ chart->top_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_VWM };
/* TODO: make the columns interactively configurable @ runtime */
- chart->proc_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_ROW, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_SYS, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[3] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WALL, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_TREE, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[5] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV, .side = VWM_SIDE_LEFT };
- chart->proc_cpu_columns[6] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_STATE, .side = VWM_SIDE_RIGHT };
- chart->proc_cpu_columns[7] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID, .side = VWM_SIDE_RIGHT };
- chart->proc_cpu_columns[8] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WCHAN, .side = VWM_SIDE_RIGHT };
-
- chart->snowflake_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID, .side = VWM_SIDE_LEFT };
- chart->snowflake_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER, .side = VWM_SIDE_LEFT };
- chart->snowflake_cpu_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_SYS, .side = VWM_SIDE_LEFT };
- chart->snowflake_cpu_columns[3] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WALL, .side = VWM_SIDE_LEFT };
- chart->snowflake_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV, .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_ROW };
+ chart->proc_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER };
+ chart->proc_cpu_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_SYS };
+ chart->proc_cpu_columns[3] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WALL };
+ chart->proc_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_TREE };
+ chart->proc_cpu_columns[5] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV };
+ chart->proc_cpu_columns[6] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_STATE };
+ chart->proc_cpu_columns[7] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID };
+ chart->proc_cpu_columns[8] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WCHAN };
+
+ chart->snowflake_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID };
+ chart->snowflake_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER };
+ chart->snowflake_cpu_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_SYS };
+ chart->snowflake_cpu_columns[3] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_WALL };
+ chart->snowflake_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV };
+
+
+ chart->top_row_columns[0] = (vwm_row_column_t){ .column = &chart->top_columns[0], .side = VWM_SIDE_RIGHT };
+
+ chart->proc_cpu_row_columns[0] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[0], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[1], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[2], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[3] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[3], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[4] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[4], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[5] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[5], .side = VWM_SIDE_LEFT };
+ chart->proc_cpu_row_columns[6] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[6], .side = VWM_SIDE_RIGHT };
+ chart->proc_cpu_row_columns[7] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[7], .side = VWM_SIDE_RIGHT };
+ chart->proc_cpu_row_columns[8] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[8], .side = VWM_SIDE_RIGHT };
+
+ chart->snowflake_cpu_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[0], .side = VWM_SIDE_LEFT };
+ chart->snowflake_cpu_row_columns[1] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[1], .side = VWM_SIDE_LEFT };
+ chart->snowflake_cpu_row_columns[2] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[2], .side = VWM_SIDE_LEFT };
+ chart->snowflake_cpu_row_columns[3] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[3], .side = VWM_SIDE_LEFT };
+ chart->snowflake_cpu_row_columns[4] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[4], .side = VWM_SIDE_LEFT };
/* add the client process to the monitoring hierarchy */
/* XXX note libvmon here maintains a unique callback for each unique callback+xwin pair, so multi-window processes work */
© All Rights Reserved