#include #include #include "MachineInfoP.h" #include #include #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); }