#include "alive.h" #include "xvars.h" #ifdef X11R5 #include #include #include #include #else #include #include #include #include #endif #include #include "LabeledPicture.h" #include "LoadFace.h" #include "ArrangeBox.h" #include "MachineInfo.h" #include #include "version.h" #include #include #include #define DEFAULT_RATIO 3.0 #ifdef BITMAP_ICON #include "bitmap/icon.icon" #endif #ifndef XtRDouble #define XtRDouble "Double" #endif static Widget title,vpane,exitButton,topbar; static Widget popdownButton; static Widget helpButton,helpScreen; static Widget helpPane,loadBox[AiFaceNum]; static Widget helpTitle; static double windowRatio = DEFAULT_RATIO; extern char *OrgFile; static AiFaceData *HelpFaces; static AiLoadBound *HelpBound; static AiLoadBound defaultLoadBound = {10,90,180,450,900}; static void exitDisplay(),popdown(),showHelp(),popdownHelp(); Widget mkWidget(); static XrmOptionDescRec optionTable[] = { {"-interval", "*interval", XrmoptionSepArg,(caddr_t)NULL}, {"-bitmapdir", "*bitmapFileDirectory", XrmoptionSepArg,(caddr_t)NULL}, {"-titlefont", "*title.font", XrmoptionSepArg,(caddr_t)NULL}, {"-windowratio","*windowRatio", XrmoptionSepArg,(caddr_t)NULL}, {"-nosort", "*sortHosts", XrmoptionNoArg, (caddr_t)"False"}, {"-loadbound", "*loadBound", XrmoptionSepArg,(caddr_t)NULL}, {"-org", "*orgFile", XrmoptionSepArg,(caddr_t)NULL}, }; static char *loadHelpText[] = { "Idle ( - %4.2f)", "Run ( - %4.2f)", "Busy ( - %4.2f)", "Heavy ( - %4.2f)", "Fever ( - %4.2f)", "Crazy (%4.2f - )", "Down", }; /* * converter from String to Double */ static void convertStr2Dbl(args,numargs,from,to) XrmValue *args; Cardinal *numargs; XrmValue *from; XrmValue *to; { double r; to->size = sizeof(double); r = atof(from->addr); to->addr = XtMalloc(sizeof(double)); *(double*)to->addr = r; } /* * makeToplevel(): creare toplevel widget */ makeToplevel(argc,argv) int *argc; char *argv[]; { XtAppContext app; XrmDatabase db; XrmValue val,realVal; char rname[64],cname[64]; char *type; char *argv0; /***** Top level *****/ Toplevel = XtInitialize("main", "xloadface", optionTable, XtNumber(optionTable), argc,argv); app = XtWidgetToApplicationContext(Toplevel); XtAppAddConverter(app,XtRString,XtRDouble, convertStr2Dbl,NULL,0); db = XtDatabase(XtDisplay(Toplevel)); for (argv0 = argv[0]+strlen(argv[0])-1; argv0 >= argv[0] && *argv0 != '/'; argv0--); argv0++; sprintf(rname,"%s.windowRatio",argv0); sprintf(cname,"%s.Ratio",argv0); if (XrmGetResource(db,rname,cname,&type,&val)) { XtConvert(Toplevel,type,&val,XtRDouble,&realVal); windowRatio = *(double*)realVal.addr; if (windowRatio <= 0) { XtAppWarning(app,"Invalid window ratio; using default value."); windowRatio = DEFAULT_RATIO; } } sprintf(rname,"%s.sortHosts",argv0); sprintf(cname,"%s.Sort",argv0); if (XrmGetResource(db,rname,cname,&type,&val)) { XtConvert(Toplevel,type,&val,XtRBoolean,&realVal); SortHosts = *(Boolean*)realVal.addr; } sprintf(rname,"%s.orgFile",argv0); sprintf(cname,"%s.OrgFile",argv0); if (XrmGetResource(db,rname,cname,&type,&val)) { #if 0 if (type != XtRString) { XtAppWarning(app,"OrgFile type is not XtRString"); } else { OrgFile = (String)val.addr; } #endif XtConvert(Toplevel, type, &val, XtRString, &realVal); OrgFile = (String)realVal.addr; } } /* * initializeWidgets(): Initialize almost all widgets and pixmaps */ initializeWidgets() { int i; static char titleString[60]; static XtCallbackRec exitCallback[] = { exitDisplay, NULL, NULL, NULL, }; static XtCallbackRec popdownCallback[] = { popdown, NULL, NULL, NULL, }; static XtCallbackRec helpCallback[] = { showHelp, (caddr_t)&helpButton, NULL, NULL, }; static XtCallbackRec helpPopdownCallback[] = { popdownHelp, NULL, NULL, NULL, }; char widgetname[64]; char loadtext[32]; /***** Pane *****/ #ifdef X11R5 vpane = mkWidget("pane",panedWidgetClass,Toplevel, XtNallowResize, (XtArgVal)True, NULL); #else vpane = mkWidget("pane",vPanedWidgetClass,Toplevel, XtNallowResize, (XtArgVal)True, NULL); #endif topbar = mkWidget("topbar",boxWidgetClass,vpane, NULL); /***** Title *****/ strcpy(titleString,"Hosts in "); for (i = 0; i < DisplayOrganNum; i++) { strcat(titleString,DisplayOrgans[i]); if (i != DisplayOrganNum-1) { strcat(titleString,","); } } title = mkWidget("title",labelWidgetClass,topbar, XtNlabel,titleString, XtNborderWidth, 0, NULL); /***** Buttons *****/ exitButton = mkWidget("exitButton",commandWidgetClass,topbar, XtNlabel,"Exit", XtNcallback,exitCallback, NULL); helpButton = mkWidget("helpButton",commandWidgetClass,topbar, XtNlabel,"Help", XtNcallback,helpCallback, NULL); /***** Face Field *****/ FaceField = mkWidget("Faces",boxWidgetClass,vpane, NULL); /***** Popup Info *****/ PopupInfo = XtCreatePopupShell("PopupInfo",transientShellWidgetClass, Toplevel,NULL,NULL); PopupPane = mkWidget("InfoPane",arrangeBoxWidgetClass,PopupInfo, AiNvertNum, 1, AiNresizeParent, True, NULL); popdownButton = mkWidget("PopdownButton",commandWidgetClass,PopupPane, XtNlabel,"Push here to popdown", XtNcallback,popdownCallback, NULL); /***** Popup Help *****/ helpScreen = XtCreatePopupShell("Help",transientShellWidgetClass, Toplevel,NULL,NULL); addFaces(); adjustWindowSize(); XtRealizeWidget(Toplevel); /***** Set Help Screen *****/ #define HELPWIDTH 200 helpPane = mkWidget("HelpPane",boxWidgetClass, helpScreen, NULL); sprintf(widgetname,"xloadface version %s",XLOADFACE_VERSION); helpTitle = mkWidget("HelpTitle",commandWidgetClass, helpPane, XtNlabel, widgetname, XtNwidth, HELPWIDTH, XtNreverseVideo, True, XtNcallback, helpPopdownCallback, NULL); HelpFaces = AiGetDefaultFaceData(loadFaceWidgetClass); HelpBound = &defaultLoadBound; for (i = 0; i < AiFaceNum; i++) { char *label; sprintf(widgetname,"LoadBox%d",i); if (i < AiLoadBoundNum) sprintf(loadtext, loadHelpText[i], (double)HelpBound->value[i]/100); else sprintf(loadtext, loadHelpText[i], (double)HelpBound->value[AiLoadBoundNum-1]/100); label = XtMalloc(strlen(loadtext)+10); strcpy(label,loadtext); loadBox[i] = mkWidget(widgetname,labeledPictureWidgetClass,helpPane, XtNborderWidth, 0, XtNwidth, HELPWIDTH, AiNtextPosition, right, AiNpixmap, HelpFaces[i].pixmap, AiNlabel, label, AiNsensitive, False, NULL); } } #ifdef BITMAP_ICON static Pixmap iconBitmap; #endif initializeBitmaps(w) Widget w; { int i; XWMHints hint; #ifdef BITMAP_ICON iconBitmap = XCreateBitmapFromData(XtDisplay(w),XtWindow(w), icon_bits,icon_width,icon_height); hint.flags = IconPixmapHint; hint.icon_pixmap = iconBitmap; XSetWMHints(XtDisplay(w),XtWindow(w),&hint); #endif } freeBitmaps(w) Widget w; { #ifdef BITMAP_ICON XFreePixmap(XtDisplay(w),iconBitmap); #endif } static void popupInformation(); /* * Create new host widget */ Widget makeHostWidget(sitedata,parent) struct whod *sitedata; Widget parent; { static XtCallbackRec popupit[] = { popupInformation, NULL, NULL, NULL, }; Widget newone; newone = mkWidget(sitedata->wd_hostname, loadFaceWidgetClass,parent, XtNcallback,popupit, XtNborderWidth,0, NULL); AiChangeLoad(newone,sitedata); return newone; } /* * Add face widgets */ addFaces() { int i; Widget w; for (i = 0; i < WhNum; i++) { if ((w = AiFindWidgetByName(FaceField,Whodata[i].wd_hostname)) == NULL) { makeHostWidget(&Whodata[i],FaceField); } else AiChangeLoad(w,&Whodata[i]); } } /* * Resize window. */ adjustWindowSize() { int width,height,xheight; int awidth,aheight; int w,h,vnum,hnum; int hsp,vsp,thsp,tvsp; int wd; int num = queryNumberOfChild(FaceField); int maxwidth = DisplayWidth(XtDisplay(Toplevel),DefaultScreen(XtDisplay(Toplevel))); int minwidth; WidgetList queryChild(), children; int i; if (num == 0) return; hnum = ceil(sqrt((double)num*windowRatio)); vnum = ceil((double)num/hnum); queryBoxSpace(FaceField,&hsp,&vsp); queryBoxSpace(topbar,&thsp,&tvsp); children = queryChild(FaceField); width = height = 0; for (i = 0; i < num; i++) { queryFigure(children[i], NULL, NULL, &awidth, &aheight); width += awidth; height += aheight; } width /= num; height /= num; w = (width+hsp)*hnum+hsp; if (w > maxwidth) { hnum = (maxwidth-hsp)/(width+hsp); w = (width+hsp)*hnum+hsp; } queryFigure(title,NULL,NULL,&minwidth,NULL); queryFigure(exitButton,NULL,NULL,&awidth,NULL); minwidth += awidth+thsp*2; queryFigure(helpButton,NULL,NULL,&awidth,NULL); minwidth += awidth+thsp; if (w < minwidth) { hnum = ceil((double)(minwidth-hsp)/(width+hsp)); w = (width+hsp)*hnum+hsp; } vnum = 1; wd = hsp; for (i = 0; i < num; i++) { queryFigure(children[i], NULL, NULL, &awidth, &aheight); if (wd+awidth > w) { wd = hsp; vnum++; } wd += awidth + hsp; } h = (height+tvsp)*vnum+tvsp; queryFigure(Toplevel, NULL, NULL, &width, &height); if (w < width) return; queryFigure(title,NULL,NULL,NULL,&height); queryFigure(exitButton, NULL,NULL,NULL,&xheight); if (height < xheight) height = xheight; queryFigure(helpButton, NULL,NULL,NULL,&xheight); if (height < xheight) height = xheight; XtResizeWidget(Toplevel, w, h+height+1+tvsp*2, queryBorderWidth(Toplevel)); } /* * Main Loop */ stay() { XtMainLoop(); } /* * Destroy all. */ static void exitDisplay(w) Widget w; { AiCleanupLoadFace(XtDisplay(Toplevel)); freeBitmaps(Toplevel); XtDestroyWidget(Toplevel); exit(0); } static Widget popupInfo; /* * Popup Info Window. */ static void popupInformation(w,client_data,event) Widget w; caddr_t client_data; XEvent *event; { XButtonEvent *bev = (XButtonEvent*)event; int dw = DisplayWidth(XtDisplay(w),DefaultScreen(XtDisplay(w))); int dh = DisplayHeight(XtDisplay(w),DefaultScreen(XtDisplay(w))); int x,y,i; static Arg popupInfoArg[2]; XtWidgetGeometry geo; AiFaceData *facedata; AiLoadBound *loadbound; char *label; XtSetArg(popupInfoArg[0],XtNborderWidth,0); XtSetArg(popupInfoArg[1],AiNsiteInfo, AiLookupLoad(w)); popupInfo = XtCreateManagedWidget("ZHOSTNAME", machineInfoWidgetClass, PopupPane, popupInfoArg, XtNumber(popupInfoArg)); XtQueryGeometry(PopupInfo,NULL,&geo); if (bev->x_root+geo.width < dw) x = bev->x_root; else x = dw-geo.width; if (bev->y_root+geo.height < dh) y = bev->y_root; else y = dh-geo.height; XtMoveWidget(PopupInfo, x, y); XtPopup(PopupInfo, XtGrabExclusive); facedata = AiGetFaceData(w); loadbound = AiGetLoadBound(w); if (facedata != HelpFaces) { for (i = 0; i < AiFaceNum; i++) AiChangePixmap(loadBox[i],facedata[i].pixmap); HelpFaces = facedata; } for (i = 0; i < AiFaceNum; i++) { label = AiGetLabel(loadBox[i]); if (i < AiLoadBoundNum) sprintf(label, loadHelpText[i], (double)loadbound->value[i]/100); else sprintf(label, loadHelpText[i], (double)loadbound->value[AiLoadBoundNum-1]/100); AiChangeLabel(loadBox[i],label); } HelpBound = loadbound; } /* * Popdown Info Window. */ static void popdown(w) Widget w; { XtDestroyWidget(popupInfo); XtPopdown(PopupInfo); } /* * Popup Help Window. */ static void showHelp(w,client_data,event) Widget w; caddr_t client_data; XEvent *event; { Widget parent = *(Widget*)client_data; int dw = DisplayWidth(XtDisplay(w),DefaultScreen(XtDisplay(w))); int dh = DisplayHeight(XtDisplay(w),DefaultScreen(XtDisplay(w))); int x,y; int px,py,cw,ch; queryFigure(parent,&px,&py,NULL,NULL); while (parent = XtParent(parent)) { queryFigure(parent,&x,&y,NULL,NULL); px += x; py += y; } queryFigure(helpScreen,NULL,NULL,&cw,&ch); if (px+cw < dw) x = px; else x = dw-cw; if (py+ch < dh) y = py; else y = dh-ch; XtMoveWidget(helpScreen, x, y); XtPopup(helpScreen, XtGrabExclusive); } /* * Popdown Info Window. */ static void popdownHelp(w) Widget w; { XtPopdown(helpScreen); } /* * Create Managed Widget * * usage: mkWidget(name, class, parent, * resource-name, resource, ... , NULL); */ Widget mkWidget(va_alist) va_dcl { va_list arg; char *name; WidgetClass class; Widget parent; String argname; XtArgVal argval; int n = 0; Arg args[20]; va_start(arg); name = va_arg(arg,char*); class = va_arg(arg,WidgetClass); parent = va_arg(arg,Widget); while (argname = va_arg(arg,String)) { argval = va_arg(arg,XtArgVal); XtSetArg(args[n],argname,argval); n++; } va_end(arg); if (n) return XtCreateManagedWidget(name,class,parent,args,n); else return XtCreateManagedWidget(name,class,parent,NULL,0); }