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