Skip to content

Commit 9d15679

Browse files
author
Austin Clements
committed
Support more than COLS CPU's by splitting the display into panes
1 parent 3b283a3 commit 9d15679

File tree

1 file changed

+108
-32
lines changed

1 file changed

+108
-32
lines changed

cpubars.c

Lines changed: 108 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,22 @@ static const struct ui_stat
416416
};
417417
#define NSTATS (sizeof(ui_stats)/sizeof(ui_stats[0]) - 1)
418418

419-
struct ui_bar
419+
// If we have too many bars to fit on the screen, we divide the screen
420+
// into "panes". Wrapping the display into these panes is handled by
421+
// the final output routine.
422+
static struct ui_pane
423+
{
424+
// start is the "length dimension" of the start of this pane
425+
// (for vertical bars, the row, relative to the bottom).
426+
// barpos is the first barpos that appears in this pane (for
427+
// vertical bars, the column). width is the size of this pane
428+
// in the width dimension (for vertical bars, the number of
429+
// columns).
430+
int start, barpos, width;
431+
} *ui_panes;
432+
static int ui_num_panes;
433+
434+
static struct ui_bar
420435
{
421436
int start, width, cpu;
422437
} *ui_bars;
@@ -479,6 +494,16 @@ ui_init(bool force_ascii)
479494
#endif
480495
}
481496

497+
static void
498+
ui_init_panes(int n)
499+
{
500+
free(ui_panes);
501+
ui_num_panes = n;
502+
if (!(ui_panes = malloc(n * sizeof *ui_panes)))
503+
epanic("out of memory");
504+
505+
}
506+
482507
void
483508
ui_layout(struct cpustats *cpus)
484509
{
@@ -496,6 +521,10 @@ ui_layout(struct cpustats *cpus)
496521
printf(" %s ", si->name);
497522
}
498523

524+
// Create one pane by default
525+
ui_init_panes(1);
526+
ui_panes[0].barpos = 0;
527+
499528
// Create bar info
500529
free(ui_bars);
501530
ui_num_bars = cpus->online + 1;
@@ -512,17 +541,18 @@ ui_layout(struct cpustats *cpus)
512541
char buf[16];
513542
snprintf(buf, sizeof buf, "%d", cpus->max);
514543
int length = strlen(buf);
515-
int w = COLS - 3;
544+
int label_len;
545+
int w = COLS - 4;
516546

517547
if ((length + 1) * cpus->online < w) {
518-
// Lay out and draw labels horizontally
519-
ui_bar_length = LINES - 3;
548+
// Lay out the labels horizontally
549+
ui_panes[0].start = 1;
550+
ui_bar_length = LINES - ui_panes[0].start - 2;
551+
label_len = 1;
520552
putp(tiparm(cursor_address, LINES, 0));
521-
printf("avg");
522553
int bar = 1;
523554
for (i = 0; i <= cpus->max; ++i) {
524555
if (cpus->cpus[i].online) {
525-
printf(" %*d", length, i);
526556
ui_bars[bar].start = 4 + (bar-1)*(length+1);
527557
ui_bars[bar].width = length;
528558
ui_bars[bar].cpu = i;
@@ -532,13 +562,26 @@ ui_layout(struct cpustats *cpus)
532562
} else {
533563
// Lay out the labels vertically
534564
int pad = 0, count = cpus->online;
535-
ui_bar_length = LINES - 2 - length;
565+
ui_panes[0].start = length;
566+
ui_bar_length = LINES - ui_panes[0].start - 2;
567+
label_len = length;
568+
569+
// XXX Making the terminal to small will crash this
536570
if (cpus->online * 2 < w) {
537571
// We have space for padding
538572
pad = 1;
539573
} else if (cpus->online >= w) {
540-
// We don't even have space for all of them
541-
ui_num_bars = w - 1;
574+
// We don't have space for all of them
575+
int totalw = 4 + cpus->online;
576+
ui_init_panes((totalw + COLS - 2) / (COLS - 1));
577+
int plength = (LINES - 2) / ui_num_panes;
578+
for (i = 0; i < ui_num_panes; ++i) {
579+
ui_panes[i].start =
580+
(ui_num_panes-i-1) * plength + length;
581+
ui_panes[i].barpos = i * (COLS - 1);
582+
ui_panes[i].width = COLS - 1;
583+
}
584+
ui_bar_length = plength - length;
542585
}
543586

544587
int bar = 1;
@@ -550,21 +593,6 @@ ui_layout(struct cpustats *cpus)
550593
bar++;
551594
}
552595
}
553-
554-
// Draw vertical labels
555-
putp(tiparm(cursor_address, LINES - length, 0));
556-
int row;
557-
for (row = 0; row < length; ++row) {
558-
printf(row == 0 ? "avg" : " ");
559-
for (bar = 1; bar < ui_num_bars; ++bar) {
560-
i = snprintf(buf, sizeof buf, "%d", ui_bars[bar].cpu);
561-
if (pad || bar == 1)
562-
putchar(' ');
563-
putchar(row < i ? buf[row] : ' ');
564-
}
565-
if (row != length - 1)
566-
putchar('\n');
567-
}
568596
}
569597

570598
// Allocate bar display buffers
@@ -584,6 +612,44 @@ ui_layout(struct cpustats *cpus)
584612
memset(ui_display, 0, ui_bar_length * ui_bar_width);
585613
memset(ui_fore, 0xff, ui_bar_length * ui_bar_width);
586614
}
615+
616+
// Trim down the last pane to the right width
617+
ui_panes[ui_num_panes - 1].width =
618+
ui_bar_width - ui_panes[ui_num_panes - 1].barpos;
619+
620+
// Draw labels
621+
char *label_buf = malloc(ui_bar_width * label_len);
622+
if (!label_buf)
623+
epanic("out of memory");
624+
memset(label_buf, ' ', ui_bar_width * label_len);
625+
int bar;
626+
for (bar = 0; bar < ui_num_bars; ++bar) {
627+
char *out = &label_buf[ui_bars[bar].start];
628+
int len;
629+
if (bar == 0) {
630+
strcpy(buf, "avg");
631+
len = 3;
632+
} else
633+
len = snprintf(buf, sizeof buf, "%d", ui_bars[bar].cpu);
634+
if (label_len == 1 || bar == 0)
635+
memcpy(out, buf, len);
636+
else
637+
for (i = 0; i < len; i++)
638+
out[i * ui_bar_width] = buf[i];
639+
}
640+
for (i = 0; i < ui_num_panes; ++i) {
641+
putp(tiparm(cursor_address, LINES - ui_panes[i].start, 0));
642+
643+
int row;
644+
for (row = 0; row < label_len; ++row) {
645+
if (row > 0)
646+
putchar('\n');
647+
fwrite(&label_buf[row*ui_bar_width + ui_panes[i].barpos],
648+
1, ui_panes[i].width, stdout);
649+
}
650+
}
651+
free(label_buf);
652+
587653
}
588654

589655
void
@@ -655,6 +721,7 @@ ui_compute_bars(struct cpustats *delta)
655721
int topStat[2] = {0, 0};
656722
int topVal[2] = {-1, -1};
657723
for (; stat < NSTATS + 1; stat++) {
724+
// XXX Wrong. Want size, not height.
658725
int val = MIN(cutoff[stat] - lo, subcells);
659726
if (val > topVal[0]) {
660727
topStat[1] = topStat[0];
@@ -718,24 +785,25 @@ ui_compute_bars(struct cpustats *delta)
718785
}
719786
}
720787

721-
void
722-
ui_show_bars(void)
788+
static void
789+
ui_show_pane(struct ui_pane *pane)
723790
{
724791
int row, col;
725792
int lastBack = -1, lastFore = -1;
726793
for (row = 0; row < ui_bar_length; row++) {
727-
putp(tiparm(cursor_address, ui_bar_length - row + 1, 0));
794+
putp(tiparm(cursor_address, LINES - pane->start - row - 1, 0));
728795

729796
// What's the width of this row? Beyond this, we can
730797
// just clear the line.
731-
int width = 0;
732-
for (col = 0; col < ui_bar_width; col++) {
798+
int endCol = 0;
799+
for (col = pane->barpos; col < pane->barpos + pane->width;
800+
col++) {
733801
if (UIXY(ui_back, col, row) != 0xff ||
734802
UIXY(ui_display, col, row) != 0)
735-
width = col + 1;
803+
endCol = col + 1;
736804
}
737805

738-
for (col = 0; col < width; col++) {
806+
for (col = pane->barpos; col < endCol; col++) {
739807
int cell = UIXY(ui_display, col, row);
740808
int back = UIXY(ui_back, col, row);
741809
int fore = UIXY(ui_fore, col, row);
@@ -765,7 +833,7 @@ ui_show_bars(void)
765833
}
766834

767835
// Clear to the end of the line
768-
if (width < ui_bar_width) {
836+
if (endCol < pane->barpos + pane->width) {
769837
if (lastBack != 0xff || lastFore != 0xff) {
770838
putp(exit_attribute_mode);
771839
lastBack = lastFore = 0xff;
@@ -775,6 +843,14 @@ ui_show_bars(void)
775843
}
776844
}
777845

846+
void
847+
ui_show_bars(void)
848+
{
849+
int pane;
850+
for (pane = 0; pane < ui_num_panes; ++pane)
851+
ui_show_pane(&ui_panes[pane]);
852+
}
853+
778854
/******************************************************************
779855
* Main
780856
*/

0 commit comments

Comments
 (0)