@@ -416,7 +416,22 @@ static const struct ui_stat
416
416
};
417
417
#define NSTATS (sizeof(ui_stats)/sizeof(ui_stats[0]) - 1)
418
418
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
420
435
{
421
436
int start , width , cpu ;
422
437
} * ui_bars ;
@@ -479,6 +494,16 @@ ui_init(bool force_ascii)
479
494
#endif
480
495
}
481
496
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
+
482
507
void
483
508
ui_layout (struct cpustats * cpus )
484
509
{
@@ -496,6 +521,10 @@ ui_layout(struct cpustats *cpus)
496
521
printf (" %s " , si -> name );
497
522
}
498
523
524
+ // Create one pane by default
525
+ ui_init_panes (1 );
526
+ ui_panes [0 ].barpos = 0 ;
527
+
499
528
// Create bar info
500
529
free (ui_bars );
501
530
ui_num_bars = cpus -> online + 1 ;
@@ -512,17 +541,18 @@ ui_layout(struct cpustats *cpus)
512
541
char buf [16 ];
513
542
snprintf (buf , sizeof buf , "%d" , cpus -> max );
514
543
int length = strlen (buf );
515
- int w = COLS - 3 ;
544
+ int label_len ;
545
+ int w = COLS - 4 ;
516
546
517
547
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 ;
520
552
putp (tiparm (cursor_address , LINES , 0 ));
521
- printf ("avg" );
522
553
int bar = 1 ;
523
554
for (i = 0 ; i <= cpus -> max ; ++ i ) {
524
555
if (cpus -> cpus [i ].online ) {
525
- printf (" %*d" , length , i );
526
556
ui_bars [bar ].start = 4 + (bar - 1 )* (length + 1 );
527
557
ui_bars [bar ].width = length ;
528
558
ui_bars [bar ].cpu = i ;
@@ -532,13 +562,26 @@ ui_layout(struct cpustats *cpus)
532
562
} else {
533
563
// Lay out the labels vertically
534
564
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
536
570
if (cpus -> online * 2 < w ) {
537
571
// We have space for padding
538
572
pad = 1 ;
539
573
} 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 ;
542
585
}
543
586
544
587
int bar = 1 ;
@@ -550,21 +593,6 @@ ui_layout(struct cpustats *cpus)
550
593
bar ++ ;
551
594
}
552
595
}
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
- }
568
596
}
569
597
570
598
// Allocate bar display buffers
@@ -584,6 +612,44 @@ ui_layout(struct cpustats *cpus)
584
612
memset (ui_display , 0 , ui_bar_length * ui_bar_width );
585
613
memset (ui_fore , 0xff , ui_bar_length * ui_bar_width );
586
614
}
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
+
587
653
}
588
654
589
655
void
@@ -655,6 +721,7 @@ ui_compute_bars(struct cpustats *delta)
655
721
int topStat [2 ] = {0 , 0 };
656
722
int topVal [2 ] = {-1 , -1 };
657
723
for (; stat < NSTATS + 1 ; stat ++ ) {
724
+ // XXX Wrong. Want size, not height.
658
725
int val = MIN (cutoff [stat ] - lo , subcells );
659
726
if (val > topVal [0 ]) {
660
727
topStat [1 ] = topStat [0 ];
@@ -718,24 +785,25 @@ ui_compute_bars(struct cpustats *delta)
718
785
}
719
786
}
720
787
721
- void
722
- ui_show_bars ( void )
788
+ static void
789
+ ui_show_pane ( struct ui_pane * pane )
723
790
{
724
791
int row , col ;
725
792
int lastBack = -1 , lastFore = -1 ;
726
793
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 ));
728
795
729
796
// What's the width of this row? Beyond this, we can
730
797
// 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 ++ ) {
733
801
if (UIXY (ui_back , col , row ) != 0xff ||
734
802
UIXY (ui_display , col , row ) != 0 )
735
- width = col + 1 ;
803
+ endCol = col + 1 ;
736
804
}
737
805
738
- for (col = 0 ; col < width ; col ++ ) {
806
+ for (col = pane -> barpos ; col < endCol ; col ++ ) {
739
807
int cell = UIXY (ui_display , col , row );
740
808
int back = UIXY (ui_back , col , row );
741
809
int fore = UIXY (ui_fore , col , row );
@@ -765,7 +833,7 @@ ui_show_bars(void)
765
833
}
766
834
767
835
// Clear to the end of the line
768
- if (width < ui_bar_width ) {
836
+ if (endCol < pane -> barpos + pane -> width ) {
769
837
if (lastBack != 0xff || lastFore != 0xff ) {
770
838
putp (exit_attribute_mode );
771
839
lastBack = lastFore = 0xff ;
@@ -775,6 +843,14 @@ ui_show_bars(void)
775
843
}
776
844
}
777
845
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
+
778
854
/******************************************************************
779
855
* Main
780
856
*/
0 commit comments