/* display.c
* $Id: display.c,v 1.6.2.5 2005/07/28 12:35:20 becker Exp $
* Ralf Becker <nctop@web.de>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ncurses.h>
#include <term.h>
#include <sys/ioctl.h>
#include "globals.h"
#include "slist.h"
#include "display.h"
#ifndef HAVE_STRUCT_LDAT
struct ldat {
chtype *text; /* text of the line */
NCURSES_SIZE_T firstchar; /* first changed character in the line */
NCURSES_SIZE_T lastchar; /* last changed character in the line */
NCURSES_SIZE_T oldindex; /* index of the line at last update */
};
#endif
static char cvsid[] = "$Id: display.c,v 1.6.2.5 2005/07/28 12:35:20 becker Exp $";
/* there are three windows
* the headerlines
* the table itself
* the msgline
*/
WINDOW *win;
WINDOW *hdrwin;
WINDOW *htwin;
WINDOW *msgwin;
/* the sizes of the windows */
int HLINES, HCOLS;
int HTLINES, HTCOLS;
int MLINES, MCOLS;
/* set to 0 */
int resize = 0;
/* scroll indikator */
int scrlpos = 0;
/* the messages */
char *msg[] = { "q,Q-Quit j,KEY_UP-up k,KEY_DOWN-down" ,
"unknown command"};
/* hoide the cursor */
void hidecursor(void) {
leaveok(hdrwin,TRUE);
leaveok(msgwin,TRUE);
leaveok(htwin,TRUE);
curs_set(0);
}
/* initialize display:
* initialize curses structures and allocate windows
* set terminal line
*/
int display_init() {
/* initialize curses display & window */
if ((win = initscr()) == NULL) {
display_kill();
fprintf(stderr, "curses error (initscr)\n");
return -1;
}
/* allocate windows */
HLINES = 2;
MLINES = 1;
HTLINES = LINES - HLINES -MLINES;
if ((hdrwin = newwin(HLINES, 0, 0, 0)) == NULL) {
display_kill();
fprintf(stderr, "curses error (newwin, hdrwin)\n");
return -1;
}
if ((htwin = newwin(HTLINES, 0, HLINES, 0)) == NULL) {
display_kill();
fprintf(stderr, "curses error (newwin, htwin)\n");
return -1;
}
if ((msgwin = newwin(MLINES, 0, LINES-1, 0)) == NULL) {
display_kill();
fprintf(stderr, "curses error (newwin, msgwin)\n");
return -1;
}
/* initialize terminal */
noecho();
cbreak();
hidecursor();
/* setting of message window */
nodelay(msgwin,TRUE);
keypad(msgwin,TRUE);
nodelay(hdrwin,TRUE);
keypad(hdrwin,TRUE);
nodelay(htwin,TRUE);
keypad(htwin,TRUE);
/* enable scrolling of table */
scrollok(htwin, TRUE);
/* print header and initial message */
display_header();
display_msg(0);
/* check scrlpos, only usefull for resize */
if (scrlpos > slist_size(hlist)-HTLINES) {
scrlpos = slist_size(hlist) - HTLINES;
if (scrlpos < 0) {
scrlpos = 0;
}
}
resize = 0;
return 0;
}
/* remove curses structures */
void display_kill() {
if (hdrwin != NULL) {
delwin(hdrwin);
hdrwin = NULL;
}
if (htwin != NULL) {
delwin(htwin);
htwin = NULL;
}
if (msgwin != NULL) {
delwin(msgwin);
msgwin = NULL;
}
win = NULL;
endwin();
}
/* get new window size and set curses variables */
void display_resize(void) {
struct winsize ws;
if (ioctl(1,TIOCGWINSZ, &ws) != -1) {
LINES = ws.ws_row;
COLS = ws.ws_col;
}
display_kill();
refresh();
display_init();
display_refresh();
}
/* display the header lines */
void display_header() {
wattron(hdrwin,A_REVERSE);
mvwprintw(hdrwin,0,0,"%-10s %-20s %-17s %-26s %3s",
"Node","Load Avg.","CPU states (%)", \
"MEM(KB)","#");
mvwprintw(hdrwin,1,0,"%-10s %-20s %5s %5s %5s %8s %8s %8s %3s",
" "," ","user","sys","idle","used","free","total"," ");
wattroff(hdrwin,A_REVERSE);
}
void display_msg(int n) {
wprintw(msgwin,"%-*s\r",COLS-1,msg[n]);
}
/* print line without WRAPPING */
void display_line(WINDOW *win, int i, int n, char *line) {
int k;
if (i > win->_maxy) {
return;
}
for (k = 0; (k <= win->_maxx) && (k < n); k++) {
win->_line[i].text[k] = line[k];
}
win->_line[i].firstchar = 0;
win->_line[i].lastchar = k;
}
/* print hoststatus line */
int print_hostline(WINDOW *win, int i, struct hostlist_t *p, int COLS,
int scroll) {
char line[81];
if (p->error != NULL) {
snprintf(line,81,"%-10.10s %-69s",p->name,p->error);
display_line(win,i,81,line);
return -1;
}
if (p->act == 0) {
snprintf(line,81,"%-10.10s %-69s",p->name,
"Resource temporarily unavailable");
display_line(win,i,81,line);
return -1;
}
snprintf(line,81,
"%-10.10s %6.2f %6.2f %6.2f %5.1f %5.1f %5.1f %8d %8d %8d %3d",
p->name,
p->hoststat.loadavg[0],
p->hoststat.loadavg[1],
p->hoststat.loadavg[2],
(double)p->hoststat.cpu[0]/10.0,
(double)p->hoststat.cpu[2]/10.0,
(double)p->hoststat.cpu[3]/10.0,
p->hoststat.mem[1],
p->hoststat.mem[2],
p->hoststat.mem[0],
p->hoststat.nusers);
display_line(win,i,81,line);
p->act-=scroll;
return 0;
}
/* print host status table */
void display(void) {
struct hostlist_t *p;
int i,k;
if (resize) {
display_resize();
}
i = -1;
k = 0;
slist_foreach(hlist, p) {
i++;
if (i < scrlpos) {
continue;
}
if (i >= scrlpos + HTLINES) {
break;
}
print_hostline(htwin, k, p,COLS,1);
k++;
}
}
/* scroll table */
void display_scroll(int n) {
struct hostlist_t *p;
int i,k,l;
int lbound, ubound;
scrlpos += n;
if (scrlpos < 0) {
scrlpos = 0;
return;
}
if (HTLINES >= slist_size(hlist)) {
scrlpos = 0;
return;
}
if (scrlpos > slist_size(hlist)-HTLINES) {
scrlpos = slist_size(hlist) - HTLINES;
return;
}
wscrl(htwin,n);
if (n > 0) {
k = HTLINES - n;
ubound = scrlpos + HTLINES;
lbound = ubound - n;
} else {
k = 0;
lbound = scrlpos;
ubound = scrlpos - n;
}
i = -1;
l=0;
slist_foreach(hlist, p) {
i++;
if (i < lbound) {
continue;
}
if (i > ubound) {
break;
}
print_hostline(htwin,k,p,COLS,0);
k++;
}
wrefresh(htwin);
}
void display_refresh(void) {
wnoutrefresh(hdrwin);
wnoutrefresh(htwin);
wnoutrefresh(msgwin);
doupdate();
}
/* handle keyboard events */
int key_handler(void) {
int ch;
switch (ch = wgetch(msgwin)) {
case 'q': { /* fall through */
}
case 'Q': {
return 0;
break;
}
case KEY_DOWN: { /* fall through */
}
case 'k': {
display_scroll(1);
break;
}
case KEY_UP: { /* fall through */
}
case 'j': {
display_scroll(-1);
break;
}
case KEY_RESIZE: { /* resize event */
break;
}
default: {
display_msg(1);
display_refresh();
}
}
return 1;
}
void sig_resize (int signal) {
resize = 1;
}
/* print host status table in batch mode */
void printlist(void) {
struct hostlist_t *p;
slist_foreach(hlist, p) {
if (p->error != NULL) {
printf("%-10.10s %-69s\n", p->name,p->error);
continue;
}
if (p->act == 0) {
printf("%-10.10s %-69s\n",
p->name,"Resource temporarily unavailable");
continue;
}
printf(
"%-10.10s %6.2f %6.2f %6.2f %5.1f %5.1f %5.1f %8d %8d %8d %3d\n",
p->name,
p->hoststat.loadavg[0],
p->hoststat.loadavg[1],
p->hoststat.loadavg[2],
(double)p->hoststat.cpu[0]/10.0,
(double)p->hoststat.cpu[2]/10.0,
(double)p->hoststat.cpu[3]/10.0,
p->hoststat.mem[1],
p->hoststat.mem[2],
p->hoststat.mem[0],
p->hoststat.nusers);
}
}
syntax highlighted by Code2HTML, v. 0.9.1