#include #include #include #include "tierra.h" #define MaxLength 64 extern Widget app_sh; extern Display *dpy; extern GC gc; extern Organism *QueueHead; static Widget mnt_sh = NULL, draw; static Window win = 0; static Pixmap pmap = 0; static Dimension width, height; static int depth; static Pixel fg, bg; static int State = 0; static unsigned short *hist = NULL, *hmax; static Pixel mcol; init_monitor() { XColor scol, ecol; hist = (unsigned short *)malloc(sizeof(short)*MaxLength*2); if (!hist) { perror("malloc"); exit(1); } hmax = hist + MaxLength; XAllocNamedColor(dpy,DefaultColormap(dpy,DefaultScreen(dpy)), "white",&scol, &ecol); mcol = scol.pixel; } reset_monitor(flag) int flag; { if (pmap) { XSetForeground(dpy,gc,bg); XFillRectangle(dpy,pmap,gc,0,0,width,height); if (flag) XClearWindow(dpy,win); } memset(hist,0,sizeof(short)*MaxLength*2); } static void draw_line(s) int s; { int k = (hist[s] + 1) / 2 - 1, km = (hmax[s] + 1) / 2 - 1; XSetForeground(dpy,gc,fg); s *= 2; if (k >= 0) { XDrawLine(dpy,pmap,gc,0,s,k,s); XDrawLine(dpy,pmap,gc,0,s+1,k,s+1); XDrawLine(dpy,win,gc,0,s,k,s); XDrawLine(dpy,win,gc,0,s+1,k,s+1); } if (km > k) { k ++; XSetForeground(dpy,gc,mcol); XDrawLine(dpy,pmap,gc,k,s,km,s); XDrawLine(dpy,pmap,gc,k,s+1,km,s+1); XDrawLine(dpy,win,gc,k,s+1,km,s+1); XDrawLine(dpy,win,gc,k,s,km,s); } } draw_monitor() { Organism *p; int s, y, k, km; if (!pmap) return; for (s = 0; s < MaxLength; s ++) if (hmax[s] > 0) draw_line(s); XCopyArea(dpy,pmap,win,gc,0,0,width,height,0,0); } inc_monitor(length) unsigned short length; { if (length >= MaxLength) length = MaxLength - 1; hist[length] ++; if (hmax[length] < hist[length]) hmax[length] = hist[length]; if (pmap) draw_line(length); } dec_monitor(length) unsigned short length; { if (length >= MaxLength) length = MaxLength - 1; hist[length] --; if (pmap) draw_line(length); } static void RedrawCB(w,cl,cd) Widget w; XtPointer cl,cd; { XmDrawingAreaCallbackStruct *d = (XmDrawingAreaCallbackStruct *)cd; XExposeEvent *e = &d->event->xexpose; XCopyArea(dpy,pmap,win,gc,e->x,e->y,e->width,e->height,e->x,e->y); } static void ClickCB(w,cl,cd) Widget w; XtPointer cl,cd; { unsigned short len; Organism *p; XmDrawingAreaCallbackStruct *d = (XmDrawingAreaCallbackStruct *)cd; XButtonEvent *e = &(d->event->xbutton); if (e->type != ButtonPress) return; len = e->y / 2; for (p = QueueHead; p; p = p->next) if (p->length == len) break; if (p) show_prog(p,(e->button == Button2)); else printf("no creature of length %d\n",len); } static void create_monitor_shell() { Arg args[2]; mnt_sh = XtCreatePopupShell("monitor", topLevelShellWidgetClass, app_sh, NULL, 0); if (!mnt_sh) { fprintf(stderr,"cannot create shell widget.\n"); exit(1); } XtSetArg(args[0],XmNheight,MaxLength*2); draw = XmCreateDrawingArea(mnt_sh,"monitor_draw",args,1); XtManageChild(draw); XtManageChild(mnt_sh); win = XtWindow(draw); XtVaGetValues(draw,XmNwidth,&width,XmNheight,&height,XmNdepth,&depth, XmNforeground,&fg,XmNbackground,&bg,NULL); pmap = XCreatePixmap(dpy,win,width,height,depth); if (!pmap) { fprintf(stderr,"cannot create pixmap for monitor.\n"); exit(1); } XSetForeground(dpy,gc,bg); XFillRectangle(dpy,pmap,gc,0,0,width,height); XtAddCallback(draw,XmNinputCallback,ClickCB,NULL); XtAddCallback(draw,XmNexposeCallback,RedrawCB,NULL); } void MonitorCB(w,cl,cd) Widget w; XtPointer cl,cd; { if ((State = !State) == 0) XtUnmanageChild(mnt_sh); else { if (!mnt_sh) create_monitor_shell(); else XtManageChild(mnt_sh); draw_monitor(); } } load_histgram(in) FILE *in; { fread(hist,sizeof(short),MaxLength*2,in); draw_monitor(); } save_histgram(out) FILE *out; { fwrite(hist,sizeof(short),MaxLength*2,out); }