// these are for the special separate bottom 'window'
#define SCREEN_ROWS ( Screen_rows - Bot_rsvd )
-#define BOT_MAXIMUM 10
-#define BOT_DELIMIT -1
-#define BOT_MISC_NS +1
+#define BOT_MAXIMUM 10 // size of tagged item array
+#define BOT_DELIMIT -1 // fenchpost with item array
+#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_item[0] = BOT_DELIMIT; \
- Bot_task = Bot_rsvd = Bot_misc = 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_item[BOT_MAXIMUM] = { BOT_DELIMIT };
-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
/*###### 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, |
+ * This guy manages that bottom margin window |
* showing misc stuff based on a single item. | */
static void bot_item_show (void) {
+ #define mkHDR fmtmk("%s for pid %d, %s", Bot_name, Bot_task, PID_VAL(EU_CMD, str, p))
struct pids_stack *p;
int i;
break;
}
if (i < PIDSmaxt) {
- bot_do_see(PID_VAL(Bot_item[0], str, p), PID_VAL(EU_CMD, str, p));
+ bot_focus(mkHDR, PID_VAL(Bot_item[0], str, p));
}
#ifdef BOT_DEAD_ZAP
else
#else
BOT_KEEP;
#endif
+ #undef mkHDR
} // end: bot_item_show
/*
- * This guy toggles between displaying a Ctrl |
+ * This guy can toggle between displaying the |
* bottom window or arranging to turn it off. | */
-static void bot_item_toggle (enum pflag item, const char *name) {
+static void bot_item_toggle (enum pflag item, const char *name, char sep) {
// if already targeted, assume user wants to turn it off ...
if (Bot_item[0] == item) {
BOT_TOSS;
} else {
- Bot_misc = 0;
+ Bot_sep = sep;
+ Bot_what = BOT_TAB_YES;
+ Bot_indx = BOT_UNFOCUS;
Bot_item[0] = item;
Bot_item[1] = BOT_DELIMIT;
Bot_name = (char*)name;
{ EU_NS5, PROCPS_NS_USER }, { EU_NS6, PROCPS_NS_UTS }
};
+
/*
* A helper function that will gather various |
* stuff for dislay by the bot_misc_show guy. | */
static char *bot_misc_hlp (struct pids_stack *p) {
- 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 "
- , procps_ns_get_name(ns_tab[i].that), PID_VAL(ns_tab[i].this, ul_int, p)));
+ 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"
+ , procps_ns_get_name(ns_tab[i].that)
+ , PID_VAL(ns_tab[i].this, ul_int, p));
+ b = scat(b, tmp);
+ if (i < (MAXTBL(ns_tab) - 1)) b = scat(b, ", ");
+ }
break;
default:
break;
/*
- * This guy manages the bottom margin window, |
+ * This guy manages that 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, PID_VAL(EU_CMD, str, p))
struct pids_stack *p;
int i;
break;
}
if (i < PIDSmaxt) {
- bot_do_see(bot_misc_hlp(p), PID_VAL(EU_CMD, str, p));
+ bot_focus(mkHDR, bot_misc_hlp(p));
}
-#ifdef BOT_DEATH
+#ifdef BOT_DEAD_ZAP
else
BOT_TOSS;
#else
BOT_KEEP;
#endif
+ #undef mkHDR
} // end: bot_misc_show
/*
- * This guy toggles between displaying a Ctrl |
+ * This guy can toggle between displaying the |
* bottom window or arranging to turn it off. | */
-static void bot_misc_toggle (int what) {
+static void bot_misc_toggle (int what, char sep) {
int i;
// if already targeted, assume user wants to turn it off ...
- if (Bot_misc == what) {
+ if (Bot_what == what) {
BOT_TOSS;
} else {
switch (what) {
default:
break;
}
- Bot_misc = what;
+ Bot_sep = sep;
+ Bot_what = what;
+ Bot_indx = BOT_UNFOCUS;
Bot_func = bot_misc_show;
Bot_task = PID_VAL(EU_PID, s_int, Curwin->ppt[Curwin->begtask]);
}
#endif
break;
case kbd_CtrlG:
- bot_item_toggle(EU_CGR, "control groups");
+ bot_item_toggle(EU_CGR, "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(eu_CMDLINE, "command line");
+ bot_item_toggle(eu_CMDLINE, "command line", ' ');
break;
case kbd_CtrlN:
- bot_item_toggle(EU_ENV, "environment");
+ bot_item_toggle(EU_ENV, "environment", ' ');
break;
case kbd_CtrlP:
- bot_misc_toggle(BOT_MISC_NS);
+ bot_misc_toggle(BOT_MISC_NS, ',');
break;
case kbd_CtrlR:
if (Secure_mode)
}
break;
case kbd_CtrlU:
- bot_item_toggle(EU_SGN, "supplementary groups");
+ bot_item_toggle(EU_SGN, "supplementary groups", ',');
break;
case kbd_ENTER: // these two have the effect of waking us
case kbd_SPACE: // from 'pselect', refreshing the display
{ 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_CtrlR, kbd_CtrlU
+ , kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK, kbd_CtrlN, kbd_CtrlP, kbd_CtrlR, kbd_CtrlU
, kbd_ENTER, kbd_SPACE, '\0' } },
{ keys_summary,
{ '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },