#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include "LoadFaceP.h"
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <math.h>
#include "bitmap/idle.icon"
#include "bitmap/run.icon"
#include "bitmap/busy.icon"
#include "bitmap/heavy.icon"
#include "bitmap/fever.icon"
#include "bitmap/crazy.icon"
#include "bitmap/down.icon"
#ifdef PACKET_LE
#define NTOHL(x) ntonl(x)
#else
#define NTOHL(x) (x)
#endif
static
AiFaceData DefaultFaceData[] = {
idle_bits, idle_width, idle_height, 0,
run_bits, run_width, run_height, 0,
busy_bits, busy_width, busy_height, 0,
heavy_bits,heavy_width,heavy_height,0,
fever_bits,fever_width,fever_height,0,
crazy_bits,crazy_width,crazy_height,0,
down_bits, down_width, down_height, 0,
};
static void Redisplay(),Initialize(),Destroy(),
LoadFaceClassPartInitialize();
static XtTimerCallbackProc updateLoad();
/* Private Data */
#define LFOffset(tag) XtOffset(LoadFaceWidget, load_face.tag)
static XtResource resources[] = {
{AiNbitmapFileDirectory, AiCBitmapFileDirectory, XtRString,sizeof(String),
LFOffset(bitmap_file_directory), XtRString, NULL},
{AiNwidgetSpecificBitmap, AiCWidgetSpecificBitmap, XtRBoolean,sizeof(Boolean),
LFOffset(widget_specific_bitmap), XtRString, (caddr_t)"FALSE"},
{AiNinterval, AiCInterval, XtRInt, sizeof(int),
LFOffset(interval), XtRString, (caddr_t)"60"},
{AiNwhodDirectory, AiCWhodDirectory, XtRString,sizeof(String),
LFOffset(whod_directory), XtRString, (caddr_t)"/usr/spool/rwho"},
{AiNshuffle, AiCShuffle, XtRBoolean,sizeof(Boolean),
LFOffset(shuffle), XtRString, (caddr_t)"TRUE"},
{AiNloadBound, AiCLoadBound, AiRLoadBound, sizeof(AiLoadBound),
LFOffset(load_bound), XtRString, "0.1:0.9:1.8:4.5:9.0"},
};
LoadFaceClassRec loadFaceClassRec = {
{
/* core_class fields */
/* superclass */ (WidgetClass)&labeledPictureClassRec,
/* class_name */ "LoadFace",
/* widget_size */ sizeof(LoadFaceRec),
/* class_initialize */ NULL,
/* class_part_initialize */ LoadFaceClassPartInitialize,
/* 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 loadFaceWidgetClass = (WidgetClass)&loadFaceClassRec;
#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 FACE(w,n) (&((LoadFaceClassRec*)XtClass(w))->load_face_class.faces_data[n])
#define ACCESS_SUPER(w,tag) (XtSuperclass(w)->core_class.tag)
#define CALL_SUPER(w,cmd,arg) (*ACCESS_SUPER(w,cmd))arg
#define CALL_SELF(w,cmd,arg) (*XtClass(w)->core_class.cmd)arg
static int
loadLevel(w,wd)
LoadFaceWidget w;
struct whod *wd;
{
int l;
if (DOWN(wd)) {
return AiDownFace;
}
l = NTOHL(wd->wd_loadav[0]);
if (l < w->load_face.load_bound.value[0])
return AiIdleFace;
else if (l < w->load_face.load_bound.value[1])
return AiRunFace;
else if (l < w->load_face.load_bound.value[2])
return AiBusyFace;
else if (l < w->load_face.load_bound.value[3])
return AiHeavyFace;
else if (l < w->load_face.load_bound.value[4])
return AiFeverFace;
else
return AiCrazyFace;
}
/*
* Converter
*/
static void
convertStr2LoadBound(args,numargs,from,to)
XrmValue *args;
Cardinal *numargs;
XrmValue *from;
XrmValue *to;
{
int i;
char buf[32];
char *p = from->addr;
char *q;
AiLoadBound *loadBound;
loadBound = (AiLoadBound*)XtMalloc(sizeof(AiLoadBound));
for (i = 0; i < AiLoadBoundNum; i++) {
for (q = buf; *p != ':' && *p != '\0'; p++) {
*(q++) = *p;
}
*q = '\0';
loadBound->value[i] = atof(buf)*100;
if (*p == ':') p++;
}
to->size = sizeof(AiLoadBound);
to->addr = (caddr_t)loadBound;
}
static void
Redisplay(new)
Widget new;
{
LoadFaceWidget w = (LoadFaceWidget)new;
CALL_SUPER(w,expose,(new));
}
#define HERE(w,tag) (w)->core_class.tag
#define SUPER(w,tag) (w)->core_class.superclass->core_class.tag
static void
LoadFaceClassPartInitialize(wc)
LoadFaceWidgetClass wc;
{
/* Inherit some properties */
if (HERE(wc,actions) == NULL) {
HERE(wc,actions) = SUPER(wc,actions);
HERE(wc,num_actions) = SUPER(wc,num_actions);
HERE(wc,tm_table) = SUPER(wc,tm_table);
}
srandom(time(0));
XtAddConverter(XtRString, AiRLoadBound, convertStr2LoadBound, NULL, 0);
}
static void
Initialize(request,new)
Widget request,new;
{
LoadFaceWidget w = (LoadFaceWidget)new;
LoadFaceClassPart *class;
Pixmap picture;
int firstInterval;
class = &((LoadFaceClassRec*)XtClass(w))->load_face_class;
if (w->load_face.widget_specific_bitmap) {
AiInitializeFaceData(w,NULL);
picture = w->load_face.faces_data[0].pixmap;
}
else {
if (!class->faces_data_initialized)
AiInitializeFaceData(w,NULL);
picture = class->faces_data[0].pixmap;
}
AiChangePixmap(w,picture,False,True);
CALL_SUPER(new,initialize,(request,new));
if (w->load_face.interval > 0) {
if (w->load_face.shuffle)
firstInterval = random()%(w->load_face.interval*2000);
else
firstInterval = w->load_face.interval*1000;
w->load_face.interval_id =
XtAppAddTimeOut(XtWidgetToApplicationContext(w),
firstInterval,
updateLoad,
(caddr_t)w);
}
w->load_face.site_data.wd_sendtime = 0; /* It shows that this data is not set. */
}
static void
Destroy(new)
Widget new;
{
LoadFaceWidget w = (LoadFaceWidget)new;
int i;
Pixmap p;
if (w->load_face.widget_specific_bitmap) {
for (i = 0; i < AiFaceNum; i++) {
p = w->load_face.faces_data[i].pixmap;
if (p)
XFreePixmap(XtDisplay(w),p);
}
}
CALL_SUPER(w,destroy, (new));
}
static XtTimerCallbackProc
updateLoad(w)
LoadFaceWidget w;
{ FILE *f;
int j;
char whodfile[256];
struct whod wd;
sprintf(whodfile,"%s/whod.%s",
w->load_face.whod_directory,
w->load_face.site_data.wd_hostname);
for (j = 0; j < 1024/sizeof(struct whoent); j++)
wd.wd_we[j].we_utmp.out_line[0] = '\0';
if (f = fopen(whodfile,"r")) {
fread(&wd,sizeof(struct whod),1,f);
fclose(f);
}
else
wd.wd_sendtime = wd.wd_recvtime = 0;
AiChangeLoad(w,&wd);
w->load_face.interval_id =
XtAppAddTimeOut(XtWidgetToApplicationContext(w),
w->load_face.interval*1000,
updateLoad,
(caddr_t)w);
}
/**** functions ****/
void
AiChangeLoad(w,loaddata)
LoadFaceWidget w;
struct whod *loaddata;
{
int oldload = 0;
int newload;
AiFaceData *newFace;
if (w->load_face.site_data.wd_sendtime) /* Is this data initialized? */
oldload = loadLevel(w,&w->load_face.site_data);
w->load_face.site_data = *loaddata;
newload = loadLevel(w,loaddata);
if (w->load_face.widget_specific_bitmap)
newFace = &w->load_face.faces_data[newload];
else
newFace = FACE(w,newload);
AiChangePixmap(w,newFace->pixmap,False,False);
if (XtIsRealized(w) && oldload != newload)
CALL_SELF(w, expose, (w));
}
static void
AiInitBitmapFromFile(w)
LoadFaceWidget w;
{
static char *iconfile[] = {
"idle.icon",
"run.icon",
"busy.icon",
"heavy.icon",
"fever.icon",
"crazy.icon",
"down.icon",
};
int i;
int width,height,xhot,yhot;
char fnbuf[256];
Pixmap p;
AiFaceData *fd;
if (w->load_face.widget_specific_bitmap == True) {
fd = w->load_face.faces_data;
}
else {
fd = ((LoadFaceClassRec*)XtClass(w))->load_face_class.faces_data;
((LoadFaceClassRec*)XtClass(w))->load_face_class.faces_data_initialized = True;
}
for (i = 0; i < AiFaceNum; i++) {
sprintf(fnbuf,"%s/%s",w->load_face.bitmap_file_directory,iconfile[i]);
if (XReadBitmapFile(XtDisplay(w),
DefaultRootWindow(XtDisplay(w)),
fnbuf,
&width,&height,
&p,
&xhot,&yhot) != BitmapSuccess) {
sprintf(fnbuf,"%s/%s: Can't open or Invalid file",
w->load_face.bitmap_file_directory,
iconfile[i]);
XtError(fnbuf);
}
fd[i].bit = NULL;
fd[i].width = width;
fd[i].height = height;
fd[i].pixmap = p;
}
}
void
AiInitializeFaceData(w,fd)
LoadFaceWidget w;
AiFaceData *fd;
{
int i;
AiFaceData *ifd;
if (fd == NULL) {
if (w->load_face.bitmap_file_directory != NULL) {
AiInitBitmapFromFile(w);
return;
}
fd = DefaultFaceData;
}
if (w->load_face.widget_specific_bitmap == True)
ifd = w->load_face.faces_data;
else {
ifd = ((LoadFaceClassRec*)XtClass(w))->load_face_class.faces_data;
((LoadFaceClassRec*)XtClass(w))->load_face_class.faces_data_initialized = True;
}
for (i = 0; i < AiFaceNum; i++) {
fd[i].pixmap = XCreateBitmapFromData(XtDisplay(w),
DefaultRootWindow(XtDisplay(w)),
fd[i].bit,
fd[i].width,
fd[i].height);
ifd[i] = fd[i];
}
}
void
AiCleanupLoadFace(d)
Display *d;
{
int i;
Pixmap p;
for (i = 0; i < AiFaceNum; i++) {
p = loadFaceClassRec.load_face_class.faces_data[i].pixmap;
if (p)
XFreePixmap(d,p);
}
}
struct whod *
AiLookupLoad(w)
LoadFaceWidget w;
{
return &w->load_face.site_data;
}
AiFaceData *
AiGetDefaultFaceData(wclass)
LoadFaceWidgetClass wclass;
{
if (!wclass->load_face_class.faces_data_initialized)
return NULL;
return wclass->load_face_class.faces_data;
}
AiFaceData *
AiGetFaceData(w)
LoadFaceWidget w;
{
if (w->load_face.widget_specific_bitmap)
return w->load_face.faces_data;
return AiGetDefaultFaceData(XtClass(w));
}
AiLoadBound *
AiGetLoadBound(w)
LoadFaceWidget w;
{
return &w->load_face.load_bound;
}
syntax highlighted by Code2HTML, v. 0.9.1