#include #include #include #include #include #include #include "help_defs.h" #include "graph.bitmap" #include "struct.h" #include "browse.h" #define MAX_LEN_SBOX 25 #define MAXLAB 50 #define MAXGROB 400 #define POINTER 0 #define ARROW 1 #define MARKER 2 /* markers start at 2 there are several of them */ #define WDMARK .001 #define HTMARK .0016 double atof(); typedef struct { float xs,ys,xe,ye; double size; short use; Window w; int type, color; } GROB; typedef struct { int type,color; int number,start,skip; double size; } MARKINFO; MARKINFO markinfo={2,0,1,0,1,1.0}; extern char *info_message; extern Atom deleteWindowAtom; LABEL lb[MAXLAB]; GROB grob[MAXGROB]; GRAPH graph[MAXPOP]; CURVE frz[MAXFRZ]; NCLINE nclines[MAXNCLINE]; GRAPH *MyGraph; extern int help_menu,screen; extern int SCALEY,CURY_OFF,CURY_OFFs,DCURYs,DCURXs; int SimulPlotFlag=0; extern int storind; extern int PSFlag; extern *text_hint[],*edit_hint[],*no_hint[]; extern Display *display; extern Window main_win,draw_win,command_pop,info_pop; int current_pop; extern unsigned int MyBackColor,MyForeColor,GrFore,GrBack; extern GC gc, gc_graph,small_gc; extern int COLOR,color_min; extern int xor_flag,DCURX,DCURY; int num_pops; int ActiveWinList[MAXPOP]; double signum(); Window make_window(); #define MAX_INTERN_SET 100 typedef struct { char *name; char *does; } INTERN_SET; #define MAX_TAB 50 typedef struct { double xlo,xhi,dx; double *y,*x; int n,flag,interp,autoeval; int xyvals; /* flag=0 if virgin array, flag=1 if already allocated; flag=2 for function interp=0 for normal interpolation, interp=1 for 'step' interp=2 for cubic spline table and finally, xyvals=1 if both x and y vals are needed (xyvals=0 is faster lookup )*/ char filename[128],name[12]; }TABULAR; extern TABULAR my_table[MAX_TAB]; extern int NTable; extern INTERN_SET intern_set[MAX_INTERN_SET]; extern int Nintern_set; select_table() { int i,index=-1,j; Window temp=main_win; char *n[MAX_TAB],key[MAX_TAB],ch; for(i=0;i=NTable){ err_msg("Not a valid table"); return -1; } return j; } get_intern_set() { char *n[MAX_INTERN_SET],key[MAX_INTERN_SET],ch; int i,j; int count=Nintern_set; Window temp=main_win; if(count==0)return; for(i=0;i=Nintern_set){ err_msg("Not a valid set"); return; } /* printf(" Got set %d \n",j); */ get_graph(); extract_internset(j); chk_delay(); redraw_params(); redraw_ics(); reset_graph(); } make_icon(icon,wid,hgt,w) char *icon; Window w; int wid,hgt; { Pixmap icon_map; XWMHints wm_hints; icon_map=XCreateBitmapFromData(display,w,icon,wid,hgt); wm_hints.initial_state=NormalState; wm_hints.input=True; wm_hints.icon_pixmap=icon_map; wm_hints.flags=StateHint|IconPixmapHint|InputHint; XSetWMProperties(display,w,NULL,NULL,NULL,0,NULL,&wm_hints,NULL); } title_text(string) char *string; { gtitle_text(string,draw_win); } gtitle_text(string,win) Window win; char *string; { XTextProperty wname,iname; GrCol(); if(win!=graph[0].w){ XStringListToTextProperty(&string,1,&wname); XStringListToTextProperty(&string,1,&iname); XSetWMProperties(display,win,&wname,&iname,NULL,0,NULL,NULL,NULL); } else { int len=strlen(string); int x,y; unsigned int w,h,bw,de; int xs,ys=2; Window root; XGetGeometry(display,win,&root,&x,&y,&w,&h,&bw,&de); xs=(w-len*DCURX)/2; if(xs<0)xs=0; Ftext(xs,ys,string,win); set_color(0); xline(0,18,w,18,win); } BaseCol(); } restore_off() { MyGraph->Restore=0; /* MyGraph->Nullrestore=0; */ } restore_on() { MyGraph->Restore=1; /* MyGraph->Nullrestore=1; */ } add_label(s,x,y,size,font) char *s; int x,y,size,font; { int i; float xp,yp; scale_to_real(x,y,&xp,&yp); for(i=0;ixhi-MyGraph->xlo)*WDMARK*size; float dy=(MyGraph->yhi-MyGraph->ylo)*HTMARK*size; while(1) { offset=48*type+3*ind; pen=sym_dir[offset]; if(pen==3)break; x2=dx*sym_dir[offset+1]+x1; y2=dy*sym_dir[offset+2]+y1; if(pen==1)line_abs(x1,y1,x2,y2); x1=x2; y1=y2; ind++; } } draw_grob(i) int i; { float xs=grob[i].xs,ys=grob[i].ys,xe=grob[i].xe,ye=grob[i].ye; set_linestyle(grob[i].color); if(grob[i].type==POINTER) line_abs(xs,ys,xe,ye); if(grob[i].type==ARROW||grob[i].type==POINTER) arrow_head(xs,ys,xe,ye,grob[i].size); if(grob[i].type>=MARKER) draw_marker(xs,ys,grob[i].size,grob[i].type-2); } arrow_head(xs,ys,xe,ye,size) float xs,ys,xe,ye; double size; { float l=xe-xs,h=ye-ys; float ar=(MyGraph->xhi-MyGraph->xlo)/(MyGraph->yhi-MyGraph->ylo); float x0=xs+size*l,y0=ys+size*h; /* float tot=(float)sqrt((double)(l*l+h*h)); */ float xp=x0+.5*size*h*ar,yp=y0-.5*size*l/ar; float xm=x0-.5*size*h*ar,ym=y0+.5*size*l/ar; line_abs(xs,ys,xp,yp); line_abs(xs,ys,xm,ym); } destroy_grob(w) Window w; { int i; for(i=0;ixv[0],MyGraph->yv[0],MyGraph->zv[0], markinfo.start+i*markinfo.skip); if(MyGraph->ThreeDFlag==0){ xs=x; ys=y; } else{ threed_proj(x,y,z,&xs,&ys); } add_grob(xs,ys,xe,ye,markinfo.size,markinfo.type,markinfo.color); } redraw_all(); } add_markers_old() { double size=1; int i; int color=0; int nm=1,nskip=1,nstart=0; float xe=0.0,ye=0.0,xs,ys,x,y,z; int type=MARKER; if(select_marker_type(&type)==0)return; if(new_float("Size: ",&size))return; if(new_int("Color: ",&color))return; if(new_int("Number of markers: ",&nm))return; if(new_int("Starting at: ", &nstart))return; if(new_int("Skip between: ", &nskip))return; for(i=0;ixv[0],MyGraph->yv[0],MyGraph->zv[0], nstart+i*nskip); if(MyGraph->ThreeDFlag==0){ xs=x; ys=y; } else{ threed_proj(x,y,z,&xs,&ys); } add_grob(xs,ys,xe,ye,size,type,color); } redraw_all(); } add_pntarr(type) int type; { double size=.1; int i1,j1,i2,j2,color=0; float xe,ye,xs,ys; Window temp; int flag; temp=main_win; if(new_float("Size: ",&size))return; if(new_int("Color: ",&color))return; /* message_box(&temp,0,SCALEY-5*DCURY,"Choose start/end"); */ MessageBox("Choose start/end"); flag=rubber(&i1,&j1,&i2,&j2,draw_win,1); /* XDestroyWindow(display,temp); */ KillMessageBox(); XFlush(display); if(flag){ scale_to_real(i1,j1,&xs,&ys); scale_to_real(i2,j2,&xe,&ye); if(i1==i2&&j1==j2)return; add_grob(xs,ys,xe,ye,size,type,color); redraw_all(); } } edit_object_com(int com) { char ch,ans,str[80]; int i,j,ilab=-1,flag,type; float x,y; float dist=1e20,dd; MessageBox("Choose Object"); flag=GetMouseXY(&i,&j); KillMessageBox(); XFlush(display); if(flag){ scale_to_real(i,j,&x,&y); /* now search all labels to find the best */ type=0; /* label = 0, arrows, etc =1 */ for(i=0;i=0&&type==0){ switch(com){ case 0: sprintf(str,"Move %s ?", lb[ilab].s); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ MessageBox("Click on new position"); flag=GetMouseXY(&i,&j); KillMessageBox(); XFlush(display); if(flag){ scale_to_real(i,j,&x,&y); lb[ilab].x=x; lb[ilab].y=y; clr_scrn(); redraw_all(); } } break; case 1 : sprintf(str,"Change %s ?", lb[ilab].s); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ new_string("Text: ",lb[ilab].s); new_int("Size 0-4 :",&lb[ilab].size); /* new_int("Font 0-times/1-symbol :",&lb[ilab].font); */ if(lb[ilab].size>4)lb[ilab].size=4; if(lb[ilab].size<0)lb[ilab].size=0; clr_scrn(); redraw_all(); } break; case 2: sprintf(str,"Delete %s ?", lb[ilab].s); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ lb[ilab].w=0; lb[ilab].use=0; clr_scrn(); redraw_all(); } break; } } if(ilab>=0&&type==1){ switch(com){ case 0: sprintf(str,"Move graphic at (%f,%f)", grob[ilab].xs,grob[ilab].ys); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ MessageBox("Reposition"); flag=GetMouseXY(&i,&j); KillMessageBox(); XFlush(display); if(flag){ scale_to_real(i,j,&x,&y); grob[ilab].xe=grob[ilab].xe-grob[ilab].xs+x; grob[ilab].ye=grob[ilab].ye-grob[ilab].ys+y; grob[ilab].xs=x; grob[ilab].ys=y; clr_scrn(); redraw_all(); } } break; case 1: sprintf(str,"Change graphic at (%f,%f)", grob[ilab].xs,grob[ilab].ys); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ if(grob[ilab].type>=MARKER) select_marker_type(&grob[ilab].type); new_float("Size ",&grob[ilab].size); new_int("Color :", &grob[ilab].color); clr_scrn(); redraw_all(); } break; case 2: sprintf(str,"Delete graphic at (%f,%f)", grob[ilab].xs,grob[ilab].ys); ans=(char)TwoChoice("Yes","No",str,"yn"); if(ans=='y'){ grob[ilab].w=0; grob[ilab].use=0; clr_scrn(); redraw_all(); } break; } } } } do_gr_objs_com(int com) { char ch; switch(com){ case 0: cput_text(); break; case 1: add_pntarr(ARROW); break; case 2: add_pntarr(POINTER); break; case 3: add_marker(); break; case 6: add_markers(); break; /*case 4: edit_object(); break; */ case 5: destroy_label(draw_win); destroy_grob(draw_win); clr_scrn(); redraw_all(); break; } } do_windows_com(int c) { int i,np=0; switch(c){ case 0: create_a_pop(); break; case 1: if(yes_no_box())kill_all_pops(); break; case 3: XLowerWindow(display,draw_win); break; case 2: destroy_a_pop(); break; case 5: set_restore(0); break; case 4: set_restore(1); break; case 6: SimulPlotFlag=1-SimulPlotFlag; break; /* default: create_a_pop(); break; */ } for(i=0;i=MAXPOP)return; select_window(graph[0].w); graph[i].Use=0; destroy_label(graph[i].w); destroy_grob(graph[i].w); XDestroySubwindows(display,graph[i].w); XDestroyWindow(display,graph[i].w); num_pops--; } init_grafs(x,y,w,h) int x,y,w,h; { int i; GrCol(); for(i=0;iNullrestore)restore_nullclines(); ps_last_pt_off(); redraw_dfield(); ps_do_color(0); draw_label(draw_win); draw_freeze(draw_win); ps_end(); } rotate3dcheck(ev) XEvent ev; { Window w=ev.xbutton.window; XEvent z; int xini,yini,dx,dy; double theta,phi; if(w==draw_win&&MyGraph->ThreeDFlag){ xini=ev.xbutton.x; yini=ev.xbutton.y; phi=MyGraph->Phi; theta=MyGraph->Theta; while(1){ XNextEvent(display,&z); if(z.type==ButtonRelease){ do_axes(); redraw_all(); hi_lite(draw_win); return 1; } if(z.type==MotionNotify){ dx=z.xmotion.x-xini; dy=z.xmotion.y-yini; MyGraph->Phi=phi-(double)dy; MyGraph->Theta=theta-(double)dx; redraw_cube_pt(MyGraph->Theta,MyGraph->Phi); } } } return 0; } do_motion_events(ev) XEvent ev; { int i=ev.xmotion.x; int j=ev.xmotion.y; float x,y; char buf[256]; slider_motion(ev); #ifdef AUTO auto_motion(ev); #endif if(ev.xmotion.window==draw_win){ scale_to_real(i,j,&x,&y); sprintf(buf,"x=%f y=%f ",x,y); canvas_xy(buf); } } do_expose(ev) XEvent ev; { int i; int cp=current_pop; Window temp; temp=draw_win; top_button_draw(ev.xany.window); expose_aplot(ev.xany.window); redraw_txtview(ev.xany.window); ani_expose(ev.xany.window); expose_my_browser(ev); /* draw_info_pop(ev.xany.window); */ RedrawMessageBox(ev.xany.window); draw_eq_list(ev.xany.window); draw_eq_box(ev.xany.window); do_box_expose(ev.xany.window); expose_slides(ev.xany.window); menu_expose(ev.xany.window); #ifdef AUTO display_auto(ev.xany.window); #endif /* if(ev.xexpose.window==menu_pop){ draw_help(); return; } */ GrCol(); for(i=0;i=MAXPOP) { respond_box(main_win,0,0,"Okay","Too many windows!"); return; } index=i; graph[index].w=XCreateSimpleWindow(display,RootWindow(display,screen),0,0,200,200,2,GrFore,GrBack); graph[index].w_info=make_window(graph[index].w,10,0,40*DCURXs,DCURYs,0); copy_graph(index,current_pop); graph[index].Width=200; graph[index].Height=200; graph[index].x0=0; graph[index].y0=0; num_pops++; make_icon(graph_bits,graph_width,graph_height,graph[index].w); XSelectInput(display,graph[index].w,KeyPressMask|ButtonPressMask |ExposureMask|ButtonReleaseMask|ButtonMotionMask); XMapWindow(display,graph[index].w); XRaiseWindow(display,graph[index].w); XSetWMProtocols(display, graph[index].w, &deleteWindowAtom, 1); select_window(graph[index].w); /* select_window(graph[0].w); select_window(graph[index].w); */ XRaiseWindow(display,graph[0].w); /* XDestroyWindow(display,temp); */ } GrCol() { XSetForeground(display,gc,GrFore); XSetBackground(display,gc,GrBack); } BaseCol() { XSetForeground(display,gc,MyForeColor); XSetBackground(display,gc,MyBackColor); } SmallGr() { XSetForeground(display,small_gc,GrFore); XSetBackground(display,small_gc,GrBack); } SmallBase() { XSetForeground(display,small_gc,MyForeColor); XSetBackground(display,small_gc,MyBackColor); } change_plot_vars(int k) { int i,ip; int np; for(i=0;ik) graph[i].xv[ip]=graph[i].xv[ip]-1; if(graph[i].yv[ip]>k) graph[i].yv[ip]=graph[i].yv[ip]-1; if(graph[i].zv[ip]>k) graph[i].zv[ip]=graph[i].zv[ip]-1; } } } } check_active_plot(int k) { int i,ip; int np; for(i=0;iw; get_draw_area(); } select_window(w) Window w; { int i; if(w==draw_win)return; GrCol(); if(w==graph[0].w)current_pop=0; else{ for(i=1;iw_info); strcpy(MyGraph->gr_info,buf); if(MyGraph->w_info==info_pop){ BaseCol(); XDrawString(display,MyGraph->w_info,gc,5,CURY_OFF,buf,strlen(buf)); } else{ SmallBase(); XDrawString(display,MyGraph->w_info,small_gc,0,CURY_OFFs,buf,strlen(buf)); /* SmallGr(); */ } } check_draw_button(ev) XEvent ev; { int k; char buf[256]; int button; int i,j; float x,y; int flag=0; Window w; button=ev.xbutton.button; w=ev.xbutton.window; i=ev.xbutton.x; j=ev.xbutton.y; if(button==1){ /* select window */ for(k=1;k