#include #include #include static Window MonitorWindow; static Pixmap MonitorPixmap; static Pixel Mfg, Mbg; static unsigned int Mwidth, Mheight; #define MXtitle "generation" #define MYoffset 20 static int MXoffset, MYspan, MXtitleX, MXtitleY, MXbase, MYbase; extern Display *dpy; extern GC gc; extern Widget MainWindow; extern XFontStruct *Gfont; extern double MaxFitness, MinFitness, *BestFitness, *AverageFitness; static int get_tic_span_int(max) int max; { int exp = 1; while (max >= 10) { max = (max + 9) / 10; exp *= 10; } if (exp < 10) return 1; else if (max < 2) return exp/10; else if (max < 3) return 2 * exp/10; else if (max < 5) return 5 * exp/10; else return exp; } static double get_tic_span_double(min,max,start) double min,max,*start; { double span = max - min, exp = 1.; if (span <= 0) { *start = min; return 1.; } if (span > 1.) while (span >= 10.) { span /= 10.; exp *= 10.; } else while (span < 1.) { span *= 10.; exp /= 10.; } if (span < 2.) exp *= .1; else if (span < 3.) exp *= .2; else if (span < 5.) exp *= .5; *start = ceil(min / exp) * exp; return exp; } #define get_x(i) (((i) * (Mwidth-MXoffset)) / xspan + MXoffset) static int get_y(v) double v; { return (int)((MaxFitness==MinFitness)?0.5: (1.-(v-MinFitness)/(MaxFitness-MinFitness))*MYspan)+MYoffset; } displayMonitor() { int i, yorigin = MYoffset+MYspan, xspan = 10; int itic, oldx, newx, y, Best, Average; double dtic, dstart; char buf[32]; extern int Generation; XSetForeground(dpy,gc,Mbg); XFillRectangle(dpy,MonitorPixmap,gc,0,0,Mwidth,Mheight); XSetForeground(dpy,gc,Mfg); XSetFont(dpy,gc,Gfont->fid); XDrawString(dpy,MonitorPixmap,gc, MXtitleX,MXtitleY,MXtitle,strlen(MXtitle)); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,yorigin,MXoffset,0); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,yorigin,Mwidth-1,yorigin); if (Generation > xspan) xspan = Generation; itic = get_tic_span_int(xspan); for (i = 0; i <= Generation; i += itic) { oldx = get_x(i); XDrawLine(dpy,MonitorPixmap,gc,oldx,yorigin-5,oldx,yorigin); sprintf(buf,"%d",i); oldx -= XTextWidth(Gfont,buf,strlen(buf))/2; XDrawString(dpy,MonitorPixmap,gc,oldx,MXbase,buf,strlen(buf)); } dtic = get_tic_span_double(MinFitness,MaxFitness,&dstart); for (; dstart <= MaxFitness; dstart += dtic) { y = get_y(dstart); XDrawLine(dpy,MonitorPixmap,gc,MXoffset,y,MXoffset+5,y); fitness_string(dstart,buf); oldx = MXoffset - XTextWidth(Gfont,buf,strlen(buf)) - 2; XDrawString(dpy,MonitorPixmap,gc,oldx,y,buf,strlen(buf)); } oldx = MXoffset; Best = get_y(BestFitness[0]); Average = get_y(AverageFitness[0]); for (i = 1; i <= Generation; i ++) { newx = get_x(i); y = get_y(BestFitness[i]); XDrawLine(dpy,MonitorPixmap,gc,oldx,Best,newx,y); Best = y; y = get_y(AverageFitness[i]); XDrawLine(dpy,MonitorPixmap,gc,oldx,Average,newx,y); Average = y; oldx = newx; } XCopyArea(dpy,MonitorPixmap,MonitorWindow,gc,0,0,Mwidth,Mheight,0,0); } static void redisplayMonitorCB(w,cl,cd) Widget w; XtPointer cl,cd; { XEvent *e = ((XmDrawingAreaCallbackStruct *)cd)->event; XCopyArea(dpy,MonitorPixmap,MonitorWindow,gc, e->xexpose.x,e->xexpose.y,e->xexpose.width,e->xexpose.height, e->xexpose.x,e->xexpose.y); } static void get_root_geometry(w,x,y,width,height) Widget w; int *x, *y; unsigned int *width,*height; { Window window, parent = XtWindow(w), root = 0, *children; unsigned int mw, mh, border, depth, n; do { window = parent; XQueryTree(dpy,window,&root,&parent,&children,&n); XFree(children); } while (root != parent); XGetGeometry(dpy,window,&root,x,y,width,height,&border,&depth); } monitor_init() { Widget monitor, work; Window root; int x, y; unsigned int width,height,border,depth; Arg args[2]; get_root_geometry(MainWindow,&x,&y,&width,&height); XtSetArg(args[0],XmNx,x+width); XtSetArg(args[1],XmNy,y); monitor = XtCreatePopupShell("Monitor", transientShellWidgetClass,MainWindow,args,2); XtManageChild(work=XmCreateDrawingArea(monitor,"work",NULL,0)); XtAddCallback(work,XmNexposeCallback,redisplayMonitorCB,NULL); XtPopup(monitor,XtGrabNone); MonitorWindow = XtWindow(work); XGetGeometry(dpy,MonitorWindow,&root,&x,&y, &Mwidth,&Mheight,&border,&depth); MonitorPixmap = XCreatePixmap(dpy,root,Mwidth,Mheight,depth); XtVaGetValues(work,XmNforeground,&Mfg,XmNbackground,&Mbg,NULL); MXoffset = XTextWidth(Gfont," 9.999",6); MYspan = Mheight - MYoffset - (Gfont->max_bounds.ascent+Gfont->max_bounds.descent)*2 - 6; MXtitleX = (Mwidth-MXoffset-XTextWidth(Gfont,MXtitle,strlen(MXtitle))) /2 + MXoffset; MXtitleY = Mheight - Gfont->max_bounds.descent - 2; MXbase = MYoffset + MYspan + Gfont->max_bounds.ascent + 2; }