void inputCB (Widget w, char * clientdata, XtcwpAxesCallbackStruct *ca) { int x=ca->x,y=ca->y,width=ca->width,height=ca->height; float x1beg=ca->x1beg,x1end=ca->x1end,x2beg=ca->x2beg,x2end=ca->x2end; int style=ca->style; XEvent *event=ca->event; int xb,yb,wb,hb; float x1begn,x1endn,x2begn,x2endn; static int firstinput=1; static float x1begs,x1ends,x2begs,x2ends; /* if first input, save initial axes limits */ if (firstinput) { x1begs = x1beg; x1ends = x1end; x2begs = x2beg; x2ends = x2end; firstinput = 0; clientdata += 0; /* dummy */ } if (event->type==ButtonPress && event->xbutton.button==Button3) { /* JG: requires extra fields in Axes.c's defaultTranslations[] to make this work. Harmless if not */ exit(0); } /* track pointer and get rubber box */ XtcwpRubberBox(XtDisplay(w),XtWindow(w),*event,&xb,&yb,&wb,&hb); /* if new box has zero width or height */ if (wb==0 || hb==0) { /* restore initial limits */ XtcwpSetAxesValues(w,x1begs,x1ends,x2begs,x2ends); /* else if non-zero zoom box */ } else { /* clip box */ if (xb<x) { wb -= x-xb; xb = x; } if (yb<y) { hb -= y-yb; yb = y; } if (xb+wb>x+width) wb = x-xb+width; if (yb+hb>y+height) hb = y-yb+height; /* determine axes limits */ if (style==XtcwpNORMAL) { x1begn = x1beg+(xb-x)*(x1end-x1beg)/width; x1endn = x1beg+(xb+wb-x)*(x1end-x1beg)/width; x2begn = x2end+(yb+hb-y)*(x2beg-x2end)/height; x2endn = x2end+(yb-y)*(x2beg-x2end)/height; } else { x1endn = x1beg+(yb+hb-y)*(x1end-x1beg)/height; x1begn = x1beg+(yb-y)*(x1end-x1beg)/height; x2begn = x2beg+(xb-x)*(x2end-x2beg)/width; x2endn = x2beg+(xb+wb-x)*(x2end-x2beg)/width; } /* set axes limits */ XtcwpSetAxesValues(w,x1begn,x1endn,x2begn,x2endn); } /* force an expose event */ XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,True); }
void inputCB (Widget w, ClientData *cd, XtcwpAxesCallbackStruct *ca) /***************************************************************************** Input event callback - currently handles rubber zoom box and pause on button 3 only. Updates dimensions and start indices of bbytes, based on user-dragged zoom box, and sets both bbytes and image to NULL, so that expose callback will make new bbytes and image. *****************************************************************************/ { int nxa=cd->nxa,nya=cd->nya, nxb=cd->nxb,nyb=cd->nyb,ixb=cd->ixb,iyb=cd->iyb; unsigned char *bbytes=cd->bbytes; float x1bega=cd->x1bega,x1enda=cd->x1enda, x2bega=cd->x2bega,x2enda=cd->x2enda; int x=ca->x,y=ca->y,width=ca->width,height=ca->height; float x1beg=ca->x1beg,x1end=ca->x1end,x2beg=ca->x2beg,x2end=ca->x2end; int style=ca->style; XEvent *event=ca->event; int xb,yb,wb,hb; int nxbn,nybn,ixbn,iybn; float x1begn,x1endn,x2begn,x2endn; static int stopflag=0; /* check for button 2 */ if (event->type==ButtonRelease && event->xbutton.button==Button2) { cd->forward = !cd->forward; return; } /* check for button 3 */ if (event->type==ButtonRelease && event->xbutton.button==Button3) { stopflag = !stopflag; if (stopflag) { XtRemoveWorkProc(cd->wpid); } else { cd->wpid = XtAppAddWorkProc(cd->ac, (XtWorkProc) readFrame,cd); } return; } /* track pointer and get rubber box */ XtcwpRubberBox(XtDisplay(w),XtWindow(w),*event,&xb,&yb,&wb,&hb); /* if zoom box has tiny width or height */ if (wb<3 || hb<3) { /* restore number of samples inside box */ nxbn = nxa; nybn = nya; /* restore indices of first samples inside box */ ixbn = 0; iybn = 0; /* restore axes limits */ x1begn = x1bega; x1endn = x1enda; x2begn = x2bega; x2endn = x2enda; /* else if valid zoom box */ } else { /* clip zoom box to lie within axes rectangle */ if (xb<x) { wb -= x-xb; xb = x; } if (yb<y) { hb -= y-yb; yb = y; } if (xb+wb>x+width) wb = x-xb+width; if (yb+hb>y+height) hb = y-yb+height; /* determine number of samples inside box (at least 2 by 2) */ nxbn = 1+NINT((float)wb/width*(nxb-1)); if (nxbn<2) nxbn = 2; nybn = 1+NINT((float)hb/height*(nyb-1)); if (nybn<2) nybn = 2; /* determine indices of first samples inside box */ ixbn = ixb+NINT((float)(xb-x)/width*(nxb-1)); if (ixbn+nxbn>ixb+nxb) ixbn = ixb+nxb-nxbn; iybn = iyb+NINT((float)(yb-y)/height*(nyb-1)); if (iybn+nybn>iyb+nyb) iybn = iyb+nyb-nybn; /* determine axes limits */ if (style==XtcwpNORMAL) { x1begn = x1beg+(ixbn-ixb)*(x1end-x1beg)/(nxb-1); x1endn = x1beg+(ixbn+nxbn-ixb-1)*(x1end-x1beg)/(nxb-1); x2begn = x2end+(iybn+nybn-iyb-1)*(x2beg-x2end)/(nyb-1); x2endn = x2end+(iybn-iyb)*(x2beg-x2end)/(nyb-1); } else { x1endn = x1beg+(iybn+nybn-iyb-1)*(x1end-x1beg)/(nyb-1); x1begn = x1beg+(iybn-iyb)*(x1end-x1beg)/(nyb-1); x2begn = x2beg+(ixbn-ixb)*(x2end-x2beg)/(nxb-1); x2endn = x2beg+(ixbn+nxbn-ixb-1)*(x2end-x2beg)/(nxb-1); } } /* set axes limits */ XtcwpSetAxesValues(w,x1begn,x1endn,x2begn,x2endn); /* set client data */ cd->nxb = nxbn; cd->nyb = nybn; cd->ixb = ixbn; cd->iyb = iybn; /* if bytes inside box exist, destroy and set pointer to NULL */ if (bbytes!=NULL) free1(bbytes); cd->bbytes = NULL; /* if image exists, destroy and set pointer to NULL */ if (cd->image!=NULL) { XDestroyImage(cd->image); cd->image = NULL; } /* clear window and force an expose event */ XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,True); }