summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Warner <james.warner@comcast.net>2022-06-15 00:00:00 -0500
committerCraig Small <csmall@dropbear.xyz>2022-06-19 20:58:51 +1000
commit04d05b9f0483311ed19529d2b405978d77108565 (patch)
tree482849f05455cd46fee02f42233a69732814b755
parent2f683d3bcf240d4b9b9b33ed5d958868114eaa51 (diff)
downloadprocps-ng-04d05b9f0483311ed19529d2b405978d77108565.tar.gz
top: extend 'Ctrl' bottom window for focus via tab key <=== port of newlib de22afc4
______________________________ original newlib message This commit introduces the 'tab' key which can be used to highlight individual elements in that bottom 'Ctrl' window. This can really help when reviewing such data. [ note, normal ongoing monitoring continues unabated ] Signed-off-by: Jim Warner <james.warner@comcast.net>
-rw-r--r--top/top.c153
-rw-r--r--top/top.h8
2 files changed, 112 insertions, 49 deletions
diff --git a/top/top.c b/top/top.c
index a1fa3f5..853a742 100644
--- a/top/top.c
+++ b/top/top.c
@@ -114,18 +114,23 @@ static int Screen_cols, Screen_rows, Max_lines;
// these are for the special separate bottom 'window'
#define SCREEN_ROWS ( Screen_rows - Bot_rsvd )
+#define BOT_UNFOCUS -1 // tab focus not established
+#define BOT_TAB_YES -1 // tab focus could be active
#define BOT_MISC_NS +1 // data for namespaces req'd
// 1 for horizontal separator
#define BOT_RSVD 1
#define BOT_KEEP Bot_func = NULL
#define BOT_TOSS do { Bot_func = NULL; Bot_lflg = 0; \
- Bot_task = Bot_rsvd = Bot_misc = 0; } \
- while (0)
+ Bot_task = Bot_rsvd = Bot_what = 0; \
+ Bot_indx = BOT_UNFOCUS; \
+ } while(0)
static int Bot_task,
- Bot_misc,
+ Bot_what,
Bot_rsvd,
+ Bot_indx = BOT_UNFOCUS,
Bot_lflg;
-static char *Bot_name;
+static char *Bot_name,
+ Bot_sep;
static void(*Bot_func)(void);
/* This is really the number of lines needed to display the summary
@@ -5084,74 +5089,113 @@ static void forest_excluded (WIN_t *q) {
/*###### Special Separate Bottom Window support ########################*/
/*
- * This guy actually draws the bottom window, |
- * including the contents passed as a string. | */
-static void bot_do_see (const char *str, const char *pgm) {
+ * This guy actually draws the parsed strings |
+ * including adding a highlight if necessary. | */
+static void bot_do (const char *str, int focus) {
+ while (*str == ' ') putchar(*(str++));
+ putp(fmtmk("%s%s%s"
+ , focus ? Cap_reverse : Cap_norm
+ , str
+ , Cap_norm));
+} // end: bot_do
+
+
+ /*
+ * This guy draws that bottom window's header |
+ * then parses/arranges to show the contents. |
+ * ( returns the number of elements printed ) | */
+static int bot_focus (const char *hdr, const char *str) {
#define maxRSVD ( Screen_rows - 1 )
- char buf[SMLBUFSIZ];
+ static char sav[BIGBUFSIZ*2];
+ const char *end, *beg;
+ char tmp[SCREENMAX];
+ int n, x;
- snprintf(buf, sizeof(buf), " %s for pid %d, %s"
- , Bot_name, Bot_task, pgm);
- if (!str || !*str || !strcmp(str, "-")) str = "n/a";
- Bot_rsvd = 1 + BOT_RSVD + (strlen(str) / Screen_cols);
- if (Bot_rsvd > maxRSVD) Bot_rsvd = maxRSVD;
- putp(fmtmk("%s%s%-*s", tg2(0, SCREEN_ROWS), Curwin->capclr_hdr, Screen_cols, buf));
- putp(fmtmk("%s%s", tg2(0, SCREEN_ROWS + 1), Cap_clr_eos));
- putp(fmtmk("%s%s", tg2(0, SCREEN_ROWS + 1), Cap_norm));
- fputs(str, stdout);
+ if (str) {
+ if (!*str || !strcmp(str, "-")) strcpy(sav, "n/a");
+ else memccpy(sav, str, '\0', sizeof(sav) - 1);
+ Bot_rsvd = 1 + BOT_RSVD + (strlen(sav) / Screen_cols);
+ if (Bot_rsvd > maxRSVD) Bot_rsvd = maxRSVD;
+ // caller itself may have used fmtmk, so we'll old school it ...
+ snprintf(tmp, sizeof(tmp), "%s%s%-*s", tg2(0, SCREEN_ROWS), Curwin->capclr_hdr, Screen_cols, hdr);
+ putp(tmp);
+ }
+ // now fmtmk is safe to use ...
+ putp(fmtmk("%s%s%s", tg2(0, SCREEN_ROWS + 1), Cap_clr_eos, Cap_norm));
+
+ beg = &sav[0];
+ x = BOT_UNFOCUS;
+
+ while (*beg) {
+ if (!(end = strchr(beg, Bot_sep)))
+ end = beg + strlen(beg);
+ if ((n = end - beg) >= sizeof(tmp))
+ n = sizeof(tmp) - 1;
+ memccpy(tmp, beg, '\0', n);
+ tmp[n] = '\0';
+ bot_do(tmp, (++x == Bot_indx));
+ if (*(beg += n))
+ putchar(*(beg++));
+ while (*beg == ' ') putchar(*(beg++));
+ }
+ return x;
#undef maxRSVD
-} // end: bot_do_see
+} // end: bot_focus
+
/*
* This guy manages the bottom margin window, |
* showing miscellaneous variable width data. | */
static void bot_item_show (void) {
- #define maxRSVD ( Screen_rows - 1 )
- char buf[SMLBUFSIZ];
- const char *p;
+ #define mkHDR fmtmk("%s for pid %d, %s", Bot_name, Bot_task, p->cmd)
+ const char *s;
+ proc_t *p;
int i;
for (i = 0; i < Frame_maxtask; i++) {
- if (Bot_task == Curwin->ppt[i]->tid)
+ p = Curwin->ppt[i];
+ if (Bot_task == p->tid)
break;
}
if (i < Frame_maxtask) {
- snprintf(buf, sizeof(buf), " %s for pid %d, %s"
- , Bot_name, Bot_task, Curwin->ppt[i]->cmd);
switch (Bot_lflg) {
case (L_CGROUP): // Ctrl-G
- p = *Curwin->ppt[i]->cgroup;
+ s = *p->cgroup;
break;
case (L_CMDLINE): // Ctrl-K
- p = *Curwin->ppt[i]->cmdline;
+ s = *p->cmdline;
break;
case (L_ENVIRON): // Ctrl-N
- p = *Curwin->ppt[i]->environ;
+ s = *p->environ;
break;
case (L_SUPGRP): // Ctrl-U
- p = Curwin->ppt[i]->supgrp;
+ s = p->supgrp;
break;
}
- bot_do_see(p, Curwin->ppt[i]->cmd);
+ bot_focus(mkHDR, s);
}
-#ifdef BOT_DEAD_ZAP
+#ifdef Bot_DEATH
else
BOT_TOSS;
#else
BOT_KEEP;
#endif
+ #undef mkHDR
} // end: bot_item_show
/*
* This guy toggles between displaying a Ctrl |
* bottom window or arranging to turn it off. | */
-static void bot_item_toggle (int flg, const char *str) {
+static void bot_item_toggle (int flg, const char *str, char sep) {
// if already targeted, assume user wants to turn it off ...
if (Bot_lflg == flg) {
BOT_TOSS;
} else {
Bot_lflg = flg;
+ Bot_sep = sep;
+ Bot_what = BOT_TAB_YES;
+ Bot_indx = BOT_UNFOCUS;
Bot_name = (char*)str;
Bot_func = bot_item_show;
Bot_task = Curwin->ppt[Curwin->begtask]->tid;
@@ -5166,15 +5210,21 @@ static char *bot_misc_hlp (proc_t *p) {
static enum ns_type ns_tab[] = {
// eu_ns1 eu_ns2 eu_ns3 eu_ns4 eu_ns5 eu_ns6
IPCNS, MNTNS, NETNS, PIDNS, USERNS, UTSNS };
- static char buf[BIGBUFSIZ], *b;
+ static char tmp[SMLBUFSIZ], buf[BIGBUFSIZ], *b;
int i;
buf[0] = '\0';
- switch (Bot_misc) {
+ switch (Bot_what) {
case BOT_MISC_NS:
b = &buf[0];
- for (i = 0; i < MAXTBL(ns_tab); i++)
- b = scat(b, fmtmk("%s: %-10lu ", get_ns_name(ns_tab[i]), p->ns[i]));
+ for (i = 0; i < MAXTBL(ns_tab); i++) {
+ // caller itself may have used fmtmk, so we'll old school it ...
+ snprintf(tmp, sizeof(tmp), "%s: %-10lu"
+ , get_ns_name(ns_tab[i])
+ , p->ns[i]);
+ b = scat(b, tmp);
+ if (i < (MAXTBL(ns_tab) - 1)) b = scat(b, ", ");
+ }
break;
default:
break;
@@ -5187,6 +5237,7 @@ static char *bot_misc_hlp (proc_t *p) {
* This guy manages the bottom margin window, |
* showing misc data based on multiple items. | */
static void bot_misc_show (void) {
+ #define mkHDR fmtmk("%s for pid %d, %s", Bot_name, Bot_task, p->cmd)
proc_t *p;
int i;
@@ -5196,23 +5247,24 @@ static void bot_misc_show (void) {
break;
}
if (i < Frame_maxtask) {
- bot_do_see(bot_misc_hlp(p), p->cmd);
+ bot_focus(mkHDR, bot_misc_hlp(p));
}
-#ifdef BOT_DEAD_ZAP
+#ifdef Bot_DEATH
else
BOT_TOSS;
#else
BOT_KEEP;
#endif
+ #undef mkHDR
} // end: bot_misc_show
/*
* This guy toggles between displaying a Ctrl |
* bottom window or arranging to turn it off. | */
-static void bot_misc_toggle (int what) {
+static void bot_misc_toggle (int what, char sep) {
// if already targeted, assume user wants to turn it off ...
- if (Bot_misc == what) {
+ if (Bot_what == what) {
BOT_TOSS;
} else {
switch (what) {
@@ -5223,7 +5275,9 @@ static void bot_misc_toggle (int what) {
default:
break;
}
- Bot_misc = what;
+ Bot_sep = sep;
+ Bot_what = what;
+ Bot_indx = BOT_UNFOCUS;
Bot_func = bot_misc_show;
Bot_task = Curwin->ppt[Curwin->begtask]->tid;
}
@@ -5598,19 +5652,26 @@ static void keys_global (int ch) {
#endif
break;
case kbd_CtrlG:
- bot_item_toggle((L_CGROUP), "control groups");
+ bot_item_toggle((L_CGROUP), "control groups", '/');
break;
+ case kbd_CtrlI:
+ if (Bot_what) {
+ ++Bot_indx;
+ if (Bot_indx > bot_focus(NULL, NULL))
+ Bot_indx = BOT_UNFOCUS;
+ }
+ break;
case kbd_CtrlK:
- bot_item_toggle((L_CMDLINE), "command line");
+ bot_item_toggle((L_CMDLINE), "command line", ' ');
break;
case kbd_CtrlN:
- bot_item_toggle((L_ENVIRON), "environment");
+ bot_item_toggle((L_ENVIRON), "environment", ' ');
break;
case kbd_CtrlP:
- bot_misc_toggle(BOT_MISC_NS);
+ bot_misc_toggle(BOT_MISC_NS, ',');
break;
case kbd_CtrlU:
- bot_item_toggle((L_SUPGRP), "supplementary groups");
+ bot_item_toggle((L_SUPGRP), "supplementary groups", ',');
break;
case kbd_ENTER: // these two have the effect of waking us
case kbd_SPACE: // from 'pselect', refreshing the display
@@ -6425,7 +6486,7 @@ static void do_key (int ch) {
{ keys_global,
{ '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
, 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
- , kbd_CtrlE, kbd_CtrlG, kbd_CtrlK, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
+ , kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
, kbd_ENTER, kbd_SPACE, '\0' } },
{ keys_summary,
{ '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },
diff --git a/top/top.h b/top/top.h
index f2703c9..d7eac62 100644
--- a/top/top.h
+++ b/top/top.h
@@ -185,6 +185,7 @@ char *strcasestr(const char *haystack, const char *needle);
#define kbd_DEL 139
#define kbd_CtrlE '\005'
#define kbd_CtrlG '\007'
+#define kbd_CtrlI '\011'
#define kbd_CtrlK '\013'
#define kbd_CtrlN '\016'
#define kbd_CtrlO '\017'
@@ -821,12 +822,13 @@ typedef struct WIN_t {
//atic inline const char *forest_display (const WIN_t *q, int idx);
//atic void forest_excluded (WIN_t *q);
/*------ Special Separate Bottom Window support ------------------------*/
-//atic void bot_do_see (const char *str, const char *pgm);
+//atic void bot_do (const char *str, int focus);
+//atic int bot_focus (const char *hdr, const char *str);
//atic void bot_item_show (void);
-//atic void bot_item_toggle (enum pflag item, const char *name);
+//atic void bot_item_toggle (enum pflag item, const char *name, char sep);
//atic char *bot_misc_hlp (proc_t *p);
//atic void bot_misc_show (void);
-//atic void bot_misc_toggle (int what);
+//atic void bot_misc_toggle (int what, char sep);
/*------ Interactive Input Tertiary support ----------------------------*/
//atic inline int find_ofs (const WIN_t *q, const char *buf);
//atic void find_string (int ch);