#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include "MachineInfoP.h"
#include <sys/types.h>
#include <netinet/in.h>
#ifdef PACKET_LE
#define NTOHL(x) ntonl(x)
#else
#define NTOHL(x) (x)
#endif
#define MIOffset(tag) XtOffset(MachineInfoWidget, machine_info.tag)
#define MACHINE_INFO_WIDTH 200
#define TITLE_OFFSET 20
#define INTER_LINE_SKIP 5
#define MAXWHO (1024/sizeof(struct whoent))
static XtResource resources[] = {
{AiNtitleFont, XtCFont, XtRFontStruct, sizeof(XFontStruct*),
MIOffset(title_font), XtRString,
"-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1",
},
{AiNloadInfoFont, XtCFont, XtRFontStruct, sizeof(XFontStruct*),
MIOffset(load_info_font), XtRString,
"-adobe-helvetica-medium-r-normal--14-140-75-75-p-77-iso8859-1",
},
{AiNuserInfoFont, XtCFont, XtRFontStruct, sizeof(XFontStruct*),
MIOffset(user_info_font), XtRString,
"-dec-terminal-bold-r-normal--14-140-75-75-c-80-iso8859-1",
},
{AiNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
MIOffset(foreground), XtRString, "Black"},
{AiNsiteInfo, AiCSiteInfo, AiRWhod, sizeof(struct whod*),
MIOffset(site_info), AiRWhod, NULL},
};
static void Initialize(), Redisplay(), Destroy();
MachineInfoClassRec machineInfoClassRec = {
{
/* core_class fields */
/* superclass */ (WidgetClass)&widgetClassRec,
/* class_name */ "MachineInfo",
/* widget_size */ sizeof(MachineInfoRec),
/* class_initialize */ NULL,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ XtInheritResize,
/* expose */ Redisplay,
/* set_values */ NULL,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ NULL,
},
};
WidgetClass machineInfoWidgetClass = (WidgetClass)&machineInfoClassRec;
#define DOWN(w) (time(0) - NTOHL((w)->wd_recvtime) >= MIN5)
#define MIN5 (5*60) /* 5 minutes in second */
#define MIN15 (15*60) /* 15 minutes in second */
#define HOUR1 (60*60) /* 1 hour in second */
#define HOUR3 (60*60*3) /* 3 hour in second */
#define DAY5 (5*24*60*60) /* 5 days in second */
#define LINE_SKIP(f) ((f)->ascent+(f)->descent+INTER_LINE_SKIP)
#define gray_width 8
#define gray_height 8
static char gray_bits[] = {
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};
static void
Initialize(request,new)
Widget request,new;
{
XGCValues gv;
MachineInfoWidget w = (MachineInfoWidget) new;
MachineInfoPart *lp = &w->machine_info;
gv.font = lp->title_font->fid;
gv.foreground = lp->foreground;
lp->title_GC = XtGetGC((Widget)w, GCFont | GCForeground, &gv);
gv.font = lp->load_info_font->fid;
lp->load_info_GC = XtGetGC((Widget)w, GCFont | GCForeground, &gv);
gv.font = lp->user_info_font->fid;
lp->user_info_GC = XtGetGC((Widget)w, GCFont | GCForeground, &gv);
gv.stipple = XCreateBitmapFromData(XtDisplay(w),
DefaultRootWindow(XtDisplay(w)),
gray_bits,
gray_width,
gray_height);
gv.fill_style = FillStippled;
lp->user_info_gray_GC =
XtGetGC((Widget)w,
GCFont | GCForeground | GCStipple | GCFillStyle,
&gv);
w->core.width = MACHINE_INFO_WIDTH;
if (lp->site_info) {
int h;
if (DOWN(lp->site_info))
h = TITLE_OFFSET+
LINE_SKIP(lp->title_font)+
LINE_SKIP(lp->load_info_font);
else
h = TITLE_OFFSET+
LINE_SKIP(lp->title_font)+
LINE_SKIP(lp->load_info_font)*3+
LINE_SKIP(lp->user_info_font)*nusers(lp->site_info);
w->core.height = h;
}
else {
w->core.height = TITLE_OFFSET+
LINE_SKIP(w->machine_info.title_font)+
LINE_SKIP(w->machine_info.load_info_font)*3;
}
}
int
nusers(wd)
struct whod *wd;
{
struct outmp *omp;
int j;
for (j = 0; j < MAXWHO; j++) {
omp = &(wd->wd_we[j].we_utmp);
if (omp->out_line[0] == '\0')
break;
}
return j;
}
static void
drawTextOnCenter(w,offset,gc,fi,p,l)
Widget w;
int offset;
GC gc;
XFontStruct *fi;
char *p;
int l;
{
int wid;
wid = XTextWidth(fi,p,l);
XDrawString(XtDisplay(w),XtWindow(w),gc,
(w->core.width-wid)/2, offset, p,l);
}
#define ONE_HOUR (60*60) /* 1 hour in sec */
static void
Redisplay(new, eve, reg)
Widget new;
XEvent *eve;
Region reg;
{
MachineInfoWidget w = (MachineInfoWidget)new;
MachineInfoPart *lp = &(w->machine_info);
int i,yo = TITLE_OFFSET;
struct outmp *omp;
static
char username[9],linename[9],msgbuf[30];
unsigned int alivetime;
int day,hour,min;
int num;
Boolean down = False;
GC userColor;
drawTextOnCenter(w,yo,lp->title_GC, lp->title_font,
lp->site_info->wd_hostname,
strlen(lp->site_info->wd_hostname));
yo += LINE_SKIP(lp->title_font);
if (DOWN(lp->site_info)) {
alivetime = time(0) - NTOHL(lp->site_info->wd_recvtime);
day = alivetime/(24*60*60);
hour = alivetime/(60*60)-day*24;
min = alivetime/60-hour*60-day*(24*60);
sprintf(msgbuf,"Sleep time %4d+%2d:%2d",day,hour,min);
drawTextOnCenter(w,yo,
lp->load_info_GC,
lp->load_info_font,
msgbuf,strlen(msgbuf));
}
else {
sprintf(msgbuf,"CPU load %4.2f",(double)NTOHL(lp->site_info->wd_loadav[0])/100);
drawTextOnCenter(w,yo,
lp->load_info_GC,
lp->load_info_font,
msgbuf,strlen(msgbuf));
yo += LINE_SKIP(lp->load_info_font);
alivetime = NTOHL(lp->site_info->wd_sendtime) - NTOHL(lp->site_info->wd_boottime);
day = alivetime/(24*60*60);
hour = alivetime/(60*60)-day*24;
min = alivetime/60-hour*60-day*(24*60);
sprintf(msgbuf,"Alive time %4d+%2d:%2d",day,hour,min);
drawTextOnCenter(w,yo,
lp->load_info_GC,
lp->load_info_font,
msgbuf,strlen(msgbuf));
yo += LINE_SKIP(lp->load_info_font);
switch (num = nusers(lp->site_info)) {
case 0:
strcpy(msgbuf,"No User");
break;
case 1:
strcpy(msgbuf,"1 User");
break;
default:
sprintf(msgbuf,"%d Users",num);
}
drawTextOnCenter(w,yo,
lp->load_info_GC,
lp->load_info_font,
msgbuf,strlen(msgbuf));
yo += LINE_SKIP(lp->load_info_font);
for (i = 0; i < num; i++) {
omp = &(lp->site_info->wd_we[i].we_utmp);
strncpy(username,omp->out_name,8);
username[8] = '\0';
strncpy(linename,omp->out_line,8);
linename[8] = '\0';
sprintf(msgbuf,"%8s on %s",username,linename);
if (NTOHL(lp->site_info->wd_we[i].we_idle) > ONE_HOUR)
userColor = lp->user_info_gray_GC;
else
userColor = lp->user_info_GC;
XDrawString(XtDisplay(w),XtWindow(w),
userColor,
10,yo,msgbuf,strlen(msgbuf));
yo += LINE_SKIP(lp->user_info_font);
}
}
XFlush(XtDisplay(w));
}
static void
Destroy(new)
Widget new;
{
MachineInfoWidget lw = (MachineInfoWidget)new;
MachineInfoPart *w = &(lw->machine_info);
XtReleaseGC(new,w->title_GC);
XtReleaseGC(new,w->load_info_GC);
XtReleaseGC(new,w->user_info_GC);
XtReleaseGC(new,w->user_info_gray_GC);
}
/**** functions ****/
void
AiSetSiteData(w,wd)
MachineInfoWidget w;
struct whod *wd;
{
int h;
if (w->machine_info.site_info == NULL)
w->machine_info.site_info = (struct whod*)XtMalloc(sizeof(struct whod));
*w->machine_info.site_info = *wd;
if (DOWN(wd))
h = TITLE_OFFSET+
LINE_SKIP(w->machine_info.title_font)+
LINE_SKIP(w->machine_info.load_info_font);
else
h = TITLE_OFFSET+
LINE_SKIP(w->machine_info.title_font)+
LINE_SKIP(w->machine_info.load_info_font)*3+
LINE_SKIP(w->machine_info.user_info_font)*nusers(wd);
XtResizeWidget(w, w->core.width, h, w->core.border_width);
}
syntax highlighted by Code2HTML, v. 0.9.1