home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / apps / math / euler / source / sysdepg.c < prev    next >
Text File  |  1993-03-25  |  37KB  |  1,645 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <math.h>
  6. #include <sys/times.h>
  7. #include <sys/types.h>
  8. #include <signal.h>
  9. #include <unistd.h> /* for chdir and getcwd */
  10.  
  11. #ifdef RS6000
  12. #include <sys/time.h>
  13. void gettimer (int, struct timestruc_t *);
  14. #endif
  15.  
  16. #define MAXPLOT 100000.0
  17.  
  18. #define WINDOW
  19.  
  20. char outputs[256];
  21.  
  22. #include "header.h"
  23. #include "sysdep.h"
  24.  
  25. #define RESERVE 16*1024l
  26. long reserve=RESERVE;
  27.  
  28. char *graph_screen=0,*text_screen=0;
  29. int graphscr=1,colors,wscreen,hscreen;
  30. int linelength,wchar,hchar,wchart,hchart,in_text=1;
  31. int userbreak=0;
  32. int planes=0x01;
  33. unsigned long mask;
  34.  
  35. #define TEXTSIZE (128*1024l)
  36.  
  37. char textstart[TEXTSIZE]={0};
  38.  
  39. int maxlines,cx,cy;
  40. int textheight,textwidth,textoffset;
  41. int cursoron=1,thchar,twchar,editor=0,scrolled=0;
  42. char *textend=textstart,*textwindow=textstart,*oldtextwindow;
  43.  
  44. long memsize=1024*1024l;
  45.  
  46. double nextcheck;
  47.  
  48. /*************** XWindow things ******************************/
  49.  
  50. #include <X11/Xlib.h>
  51. #include <X11/Xutil.h>
  52. #include <X11/keysym.h>
  53. #include <X11/cursorfont.h>
  54.  
  55. #define maxcolors 16
  56.  
  57. Display *display;
  58. char sdisp[64]="";
  59. int screen, depth;
  60. int winit=0;
  61. Window window;
  62. GC gc,cleargc,stipplegc,textgc,invtextgc;
  63. Pixmap stipple[64];
  64. unsigned long blackpixel, whitepixel;
  65. Colormap colormap;
  66. int usedcolors=maxcolors;
  67. unsigned long color[maxcolors];
  68. char *colorname[maxcolors]=
  69. {
  70.     "White","Black","Green","Lightblue","Blue","SteelBlue","Khaki","Tan",
  71.     "Grey","Yellow","Green","Red","LightBlue","LightSteelBlue",
  72.     "LimeGreen","Navy"
  73. };
  74. XFontStruct *font,*textfont;
  75. Pixmap pixmap;
  76.  
  77. char fontname[32]=GFONT;
  78. char textfontname[32]=FONT;
  79. int userwidth=700,userheight=700,userx=0,usery=0,usersize=0,userpos=0;
  80.  
  81. #include "icon.h"
  82.  
  83. void process_event (XEvent *event);
  84.  
  85. void computechar (void)
  86. {
  87.     hchar=(font->ascent+font->descent+2)*1024l/hscreen;
  88.     wchar=(XTextWidth(font,"m",1))*1024l/wscreen;
  89. }
  90.  
  91. void initX (void)
  92. /* Sets up the connection to the X server */
  93. {    
  94.     display=XOpenDisplay(sdisp);
  95.     if (!display)
  96.     {       
  97.         fprintf(stderr,"ERROR: Connetion to X server %s failed.\n",
  98.             sdisp);
  99.         exit(1);
  100.     }
  101.     screen=DefaultScreen(display); /* screen # */
  102.     depth=DefaultDepth(display,screen); /* color depth */
  103.     switch(depth)
  104.     {
  105.         case 1 : usedcolors=2; break;
  106.         case 2 : usedcolors=4; break;
  107.         case 3 : usedcolors=8; break;
  108.         default : usedcolors=maxcolors; break;
  109.     }
  110.     blackpixel=BlackPixel(display,screen);
  111.     whitepixel=WhitePixel(display,screen);
  112.  
  113.     /* load a font */
  114.     textfont=XLoadQueryFont(display,textfontname);
  115.     if (!textfont)
  116.     {
  117.         fprintf(stderr,"Cannot find %s font\n",textfontname);
  118.         exit(1);
  119.     }
  120.     textheight=textfont->ascent+textfont->descent+2;
  121.     textwidth=XTextWidth(textfont,"m",1);
  122.     if (textwidth!=XTextWidth(textfont,"i",1))
  123.     {
  124.         fprintf(stderr,
  125.             "You cannot use the proportional font %s!\n",textfontname);
  126.         exit(1);
  127.     }
  128.     textoffset=textwidth/2;
  129.  
  130.     font=XLoadQueryFont(display,fontname);
  131.     if (!font)
  132.     {
  133.         fprintf(stderr,"Cannot find %s font\n",fontname);
  134.         exit(1);
  135.     }
  136.  
  137.     XFlush(display);
  138.  
  139. }
  140.  
  141. void quitX (void)
  142. /* Disconnect to server */
  143. {   
  144.     static int quitted=0;
  145.     if (quitted) return;
  146.     XDestroyWindow(display,window);
  147.     XFreeFont(display,font);
  148.     XFreePixmap(display,pixmap);
  149.     XCloseDisplay(display);
  150. }
  151.  
  152. int createGC (Window window, GC *gc)
  153. /* Create a new graphic context */
  154. {    
  155.     XGCValues gcvalues;
  156.     *gc=XCreateGC(display,window,(unsigned long)0,&gcvalues);
  157.     if (*gc==0) exit(1);
  158.     return 1;
  159. }
  160.  
  161. void create_contexts (Window window)
  162. {
  163.     int i,j,k,st;
  164.     unsigned char byte,bits[512];
  165.     XColor rgb,hardware;
  166.     
  167.     colormap=DefaultColormap(display,screen);
  168.     color[0]=whitepixel;
  169.     color[1]=blackpixel;
  170.     for (i=0; i<usedcolors; i++)
  171.     {
  172.         st=XLookupColor(display,colormap,colorname[i],&rgb,&hardware);
  173.         if (st)
  174.         {    st=XAllocColor(display,colormap,&hardware);
  175.             if (st) color[i]=hardware.pixel;
  176.             else color[i]=blackpixel;
  177.         }
  178.         else color[i]=whitepixel;
  179.     }
  180.  
  181.     createGC(window,&gc);
  182.     XSetForeground(display,gc,blackpixel);
  183.     XSetBackground(display,gc,whitepixel);
  184.     XSetFont(display,gc,font->fid);
  185.                 
  186.     createGC(window,&cleargc);
  187.     XSetForeground(display,cleargc,whitepixel);
  188.     XSetBackground(display,cleargc,blackpixel);
  189.  
  190.     createGC(window,&stipplegc);
  191.     XSetForeground(display,stipplegc,blackpixel);
  192.     XSetBackground(display,stipplegc,whitepixel);
  193.     XSetFillStyle(display,stipplegc,FillOpaqueStippled);
  194.     
  195.     for (i=0; i<64; i++)
  196.     {    for (j=0; j<512; j++)
  197.         {    byte=0;
  198.             if (i==0) byte=255;
  199.             else if (i==63) byte=0;
  200.             else for (k=0; k<8; k++) byte=(byte<<1)|((rand()&63)>i);
  201.             bits[j]=byte;
  202.         }
  203.         stipple[i]=XCreateBitmapFromData(display,window,bits,64,64);
  204.     }
  205.  
  206.     createGC(window,&textgc);
  207.     XSetForeground(display,textgc,blackpixel);
  208.     XSetBackground(display,textgc,whitepixel);
  209.     XSetFont(display,textgc,textfont->fid);
  210.  
  211.     createGC(window,&invtextgc);
  212.     XSetForeground(display,invtextgc,whitepixel);
  213.     XSetBackground(display,invtextgc,blackpixel);
  214.     XSetFont(display,invtextgc,textfont->fid);
  215. }    
  216.  
  217. Window open_window (int x, int y, int width, int height, int flag)
  218. /* create and open a window plus a graphic context and a pximap */
  219. {    
  220.     XSetWindowAttributes attributes;
  221.     XSizeHints sizehints;
  222.     Window window;
  223.     Pixmap iconpixmap;
  224.     XWMHints iconhints;
  225.     /* XClassHint classhints; */
  226.     unsigned int cursorshape;
  227.     Cursor cursor;
  228.  
  229.     /* window attributes */
  230.     attributes.border_pixel=BlackPixel(display,screen);
  231.     attributes.background_pixel=WhitePixel(display,screen);
  232.  
  233.     mask= CWBackPixel | CWBorderPixel;
  234.  
  235.     /* create the window */
  236.     window= XCreateWindow(display,RootWindow(display,screen),
  237.         x,y,width,height,
  238.         2, /* Border width */
  239.         depth,
  240.         InputOutput,
  241.         CopyFromParent,
  242.         mask,
  243.         &attributes);
  244.  
  245.     /* Icon setting */
  246.     iconpixmap= XCreateBitmapFromData(display,window,
  247.         icon_bits,icon_width,icon_height);
  248.     iconhints.icon_pixmap=iconpixmap;
  249.     iconhints.initial_state=NormalState;
  250.     iconhints.flags=IconPixmapHint|StateHint;
  251.     XSetWMHints(display,window,&iconhints);
  252.  
  253.     /* Cursor */
  254.     cursorshape=XC_dotbox;
  255.     cursor=XCreateFontCursor(display,cursorshape);
  256.     XDefineCursor(display,window,cursor);
  257.  
  258.     /* class hints */
  259.     /* classhints.res_name="Euler";
  260.     classhints.res_class="Euler";
  261.     XSetClassHint(display,window,classhints); */
  262.  
  263.     /* Window and Icon name */
  264.     XStoreName(display,window,"Euler");
  265.     XSetIconName(display,window,"Euler");
  266.  
  267.     /* size hints */
  268.     sizehints.flags=PMinSize;
  269.     if (userpos) sizehints.flags|= USPosition | USSize;
  270.     else sizehints.flags|= PPosition | USSize;
  271.     sizehints.x=x;
  272.     sizehints.y=y;
  273.     sizehints.width=width;
  274.     sizehints.height=height;
  275.     sizehints.min_width=200;
  276.     sizehints.min_height=200;
  277.     XSetNormalHints(display,window,&sizehints);
  278.  
  279.     create_contexts(window);
  280.  
  281.     /* events, we like to receive */
  282.     mask=KeyPressMask|ExposureMask|ButtonPressMask|StructureNotifyMask;
  283.     XSelectInput(display,window,mask);
  284.  
  285.     /* show the window */
  286.     XMapWindow(display,window);
  287.  
  288.     /* create a pixmap of same size */
  289.     pixmap=XCreatePixmap(display,window,width,height,depth);
  290.     XFillRectangle(display,pixmap,cleargc,0,0,width,height);
  291.     XFlush(display);
  292.  
  293.     return window;
  294. }
  295.  
  296. void computetext (void)
  297. {
  298.     maxlines=(hscreen-2*textoffset)/textheight;
  299.     linelength=(wscreen-2*textoffset)/textwidth;
  300.     linew=linelength/fieldw;
  301. }
  302.  
  303. void grafik (void)
  304. /* switch to a graphic screen */
  305. {
  306.     if (!winit)
  307.     {    
  308.         initX();
  309.         atexit(quitX);
  310.         if (usersize)
  311.         {    
  312.             userwidth=abs(userwidth);
  313.             if (userwidth<256) userwidth=256;
  314.             if (userwidth>DisplayWidth(display,screen))
  315.                 userwidth=DisplayWidth(display,screen);
  316.             userheight=abs(userheight);
  317.             if (userheight<256) userheight=256;
  318.             if (userheight>DisplayHeight(display,screen))
  319.                 userheight=DisplayHeight(display,screen);
  320.         }
  321.         else
  322.         {
  323.             userwidth=DisplayWidth(display,screen)/3*2;
  324.             userheight=DisplayHeight(display,screen)/3*2;
  325.         }
  326.         if (userpos)
  327.         {
  328.             if (userx<0) userx=DisplayWidth(display,screen)
  329.                 +userx-userwidth;
  330.             if (usery<0) usery=DisplayHeight(display,screen)
  331.                 +usery-userheight;
  332.             if (userx<0) userx=0;
  333.             if (usery<0) usery=0;
  334.         }
  335.         else
  336.         {
  337.             userx=usery=0;
  338.         }
  339.         window=open_window(userx,usery,userwidth,userheight,0);
  340.         wscreen=userwidth;
  341.         hscreen=userheight;
  342.         computetext();
  343.         computechar();
  344.         winit=1;
  345.     }
  346. }
  347.  
  348. void setcolor (int c)
  349. {       
  350.     static oldcolor=-1;
  351.     if (c>=usedcolors) c=usedcolors-1;
  352.     if (c<0) c=0;
  353.     if (c!=oldcolor)
  354.     {
  355.         XSetForeground(display,gc,color[c]);
  356.         oldcolor=c;
  357.     }
  358. }
  359.  
  360. #ifdef WINDOW
  361. #define draw(x1,x2,y1,y2) XDrawLine(display,pixmap,gc,x1,x2,y1,y2),\
  362.     XDrawLine(display,window,gc,x1,x2,y1,y2)
  363. #define plot(x1,x2) XDrawPoint(display,pixmap,gc,x1,x2),\
  364.     XDrawPoint(display,window,gc,x1,x2)
  365. #else
  366. #define draw(x1,x2,y1,y2) XDrawLine(display,pixmap,gc,x1,x2,y1,y2)
  367. #define plot(x1,x2) XDrawPoint(display,pixmap,gc,x1,x2)
  368. #endif
  369.  
  370. /*************** graphics and GEM initialization *************/
  371.  
  372. int memory_init (void)
  373. /***** memory_init
  374.     get colors, wscreen, hscreen.
  375.     get the graphics screen.
  376.     get all memory (minus reservefor editor) for stack.
  377. *****/
  378. {    
  379.     long size;
  380.     size=memsize;
  381.     if (size<64*1024l) size=64*1024l;
  382.     if (size<reserve) return 0;
  383.     ramstart=(char *)malloc(size-reserve);
  384.     if (!ramstart) return 0;
  385.     ramend=ramstart+size;
  386.     linelength=70;
  387.     hchar=8;
  388.     wchar=8;
  389.     return 1;
  390. }
  391.  
  392. int shrink (size_t size)
  393. {    
  394.     if (size==0) return 0;
  395.     return 1;
  396. }
  397.  
  398. /******************** some graphic support functions ************/
  399.  
  400. int column (double c)
  401. {    
  402.     long res;
  403.     res=(long)((c*wscreen)/1024);
  404.     return (int)res;
  405. }
  406.  
  407. int row (double c)
  408. {    
  409.     long res;
  410.     res=(long)((c*hscreen)/1024);
  411.     return (int)res;
  412. }
  413.  
  414. void longwrite (double n)
  415. {    
  416.     int k[1];
  417.     k[0]=(long)(n*1000.0);
  418.     if (metafile) fwrite(k,sizeof(long),1,metafile);
  419. }
  420.  
  421. void intwrite (int n)
  422. {    
  423.     int k[1];
  424.     k[0]=n;
  425.     if (metafile) fwrite(k,sizeof(int),1,metafile);
  426. }
  427.  
  428. void stringwrite (char *s)
  429. {    
  430.     int c;
  431.     if (metafile)
  432.     {    
  433.         c=0;
  434.         while (*s) { 
  435.             putc(*s++,metafile); 
  436.             c++; 
  437.         }
  438.         putc(0,metafile); 
  439.         c++;
  440.         if (c%2) putc(0,metafile);
  441.     }
  442. }
  443.  
  444. void refresh_window (void);
  445.  
  446. void graphic_mode (void)
  447. /***** graphics
  448.     switch to graphics. text should not be deleted.
  449. *****/
  450. {   
  451.     if (in_text)
  452.     {
  453.         in_text=0;
  454.         refresh_window();
  455.     }
  456. }
  457.  
  458. void text_mode (void)
  459. /***** text_mode
  460.     switch to text. graphics should not be deleted.
  461. *****/
  462. {    
  463.     if (!in_text)
  464.     {
  465.         in_text=1;
  466.         refresh_window();
  467.     }
  468. }
  469.  
  470. int oldst=-1,oldcol=-1,oldwidth=-1;
  471.  
  472. void setline (int w, int st)
  473. {    if (w==1) w=0;
  474.     if (oldwidth==w && oldst==st) return;
  475.     oldst=st;
  476.     switch (st)
  477.     {    case line_dotted :
  478.         case line_dashed : st=LineOnOffDash; break;
  479.         default : st=LineSolid; break;
  480.     }
  481.     XSetLineAttributes(display,gc,w,st,CapRound,JoinRound);
  482.     oldwidth=w;
  483. }
  484.  
  485. void gline (double c, double r, double c1, double r1, int col, int st, int width)
  486. /***** gline
  487.     draw a line.
  488. *****/
  489. {   
  490.     if (fabs(r)>MAXPLOT) return;
  491.     if (fabs(c)>MAXPLOT) return;
  492.     if (fabs(r1)>MAXPLOT) return;
  493.     if (fabs(c1)>MAXPLOT) return;
  494.     if (metafile)
  495.     {    
  496.         intwrite(1);
  497.         longwrite(c); 
  498.         longwrite(r); 
  499.         longwrite(c1); 
  500.         longwrite(r1);
  501.         intwrite(col); 
  502.         intwrite(st);
  503.         intwrite(width);
  504.     }
  505.     if (st==line_none) setcolor(0);
  506.     else setcolor(col);
  507.     setline(width,st);
  508.     draw(column(c),row(r),column(c1),row(r1));
  509. }
  510.  
  511. void gmarker (double c, double r, int col, int type)
  512. /***** gmarker
  513.     plot a single marker on screen.
  514. *****/
  515. {    
  516.     if (fabs(r)>MAXPLOT) return;
  517.     if (fabs(c)>MAXPLOT) return;
  518.     if (metafile)
  519.     {    
  520.         intwrite(0x0204);
  521.         intwrite(c); 
  522.         intwrite(r);
  523.         intwrite(col); 
  524.         intwrite(type);
  525.     }
  526.     setcolor(col);
  527.     switch(type)
  528.     {
  529.     case marker_dot : plot(column(c),row(r)); break;
  530.     case marker_plus :    
  531.         draw(column(c+10),row(r),column(c-10),row(r));
  532.         draw(column(c),row(r-10),column(c),row(r+10));
  533.         break;
  534.     case marker_square :
  535.     case marker_circle :
  536.         draw(column(c+10),row(r-10),column(c+10),row(r+10));
  537.         draw(column(c+10),row(r+10),column(c-10),row(r+10));
  538.         draw(column(c-10),row(r+10),column(c-10),row(r-10));
  539.         draw(column(c-10),row(r-10),column(c+10),row(r-10));
  540.         break;
  541.     case marker_diamond :
  542.         draw(column(c),row(r-10),column(c+10),row(r));
  543.         draw(column(c+10),row(r),column(c),row(r+10));
  544.         draw(column(c),row(r+10),column(c-10),row(r));
  545.         draw(column(c-10),row(r),column(c),row(r-10));
  546.         break;
  547.     case marker_star :
  548.         draw(column(c+10),row(r),column(c-10),row(r));
  549.         draw(column(c),row(r-10),column(c),row(r+10));        
  550.     default :
  551.         draw(column(c+10),row(r-10),column(c-10),row(r+10));
  552.         draw(column(c-10),row(r-10),column(c+10),row(r+10));
  553.     }
  554. }
  555.  
  556. void gfill (double c[], int st, int n, int connect[])
  557. /***** gfill
  558.     fill an area given by n pairs of points (in c: x,y,x,y,...)
  559.     with the style.
  560. *****/
  561. {    
  562.     int i,cc[64],ci[64],j,k,count;
  563.     XPoint points[64];
  564.     if (n>32) return;
  565.     for (i=0; i<2*n; i++) if (fabs(c[i])>MAXPLOT) return;
  566.     if (metafile)
  567.     {    
  568.         intwrite(3);
  569.         intwrite(n);
  570.         for (i=0; i<2*n; i+=2)
  571.         {    
  572.             longwrite(c[i]); 
  573.             longwrite(c[i+1]);
  574.             intwrite(connect[i]);
  575.         }
  576.         intwrite(st);
  577.     }
  578.     for (i=0; i<2*n; i+=2) ci[i]=(int)column(c[i]);
  579.     for (i=1; i<2*n; i+=2) ci[i]=(int)row(c[i]);
  580.     for (i=0; i<n; i++) { 
  581.         points[i].x=ci[2*i]; 
  582.         points[i].y=ci[2*i+1]; 
  583.     }
  584.     setcolor(st==fill_filled?0:2);
  585. #ifdef WINDOW
  586.     XFillPolygon(display,window,gc,points,n,Complex,CoordModeOrigin);
  587. #endif
  588.     XFillPolygon(display,pixmap,gc,points,n,Complex,CoordModeOrigin);
  589.     i=0;
  590.     setline(0,line_solid);
  591.     setcolor(1);
  592.     while (i<n)
  593.     {    
  594.         j=0; 
  595.         count=0;
  596.         while (i<n && connect[i])
  597.         {    
  598.             cc[j++]=ci[2*i]; 
  599.             cc[j++]=ci[2*i+1];
  600.             i++; 
  601.             count++;
  602.         }
  603.         if (i==n)
  604.         {    
  605.             cc[j++]=ci[0]; 
  606.             cc[j++]=ci[1]; 
  607.             count++;
  608.         }
  609.         else
  610.         {    
  611.             cc[j++]=ci[2*i]; 
  612.             cc[j++]=ci[2*i+1]; 
  613.             count++;
  614.         }
  615.         for (k=0; k<count-1; k++)
  616.             draw(cc[2*k],cc[2*k+1],cc[2*k+2],cc[2*k+3]);
  617.         while (i<n && !connect[i]) i++;
  618.     }
  619. }
  620.  
  621. int oldstipple=-1,oldscolor=-1;
  622.  
  623. void sethue (double hue, int col)
  624. {    int k,nostipple=0;
  625.     if (col>=usedcolors) col=usedcolors-1;
  626.     else if (col==0)
  627.     {    hue-=floor(hue); col=floor(hue*(usedcolors-2)*0.9999)+2;
  628.         nostipple=1;
  629.     }
  630.     else if (col<0)
  631.     {    hue-=floor(hue);
  632.         hue*=(usedcolors-2)*0.9999;
  633.         col=floor(hue)+2;
  634.     }
  635.     if (oldscolor!=col) XSetForeground(display,stipplegc,color[oldscolor=col]);
  636.     if (!nostipple)
  637.     {    hue-=floor(hue); hue*=0.9999; k=(int)(hue*64);
  638.     }
  639.     else k=0;
  640.     if (k!=oldstipple) XSetStipple(display,stipplegc,stipple[oldstipple=k]);
  641. }
  642.  
  643. void gfillh (double c[], double hue, int color, int connect)
  644. /***** gfillh
  645.     fill an area given by 4 pairs of points (in c: x,y,x,y,...)
  646.     with the hue and color. connect determines, if an outline is
  647.     to be drawn.
  648. *****/
  649. {    
  650.     int i,ci[8];
  651.     XPoint points[5];
  652.     for (i=0; i<8; i++) if (fabs(c[i])>MAXPLOT) return;
  653.     if (metafile)
  654.     {    
  655.         intwrite(7);
  656.         for (i=0; i<8; i+=2)
  657.         {    
  658.             longwrite(c[i]); 
  659.             longwrite(c[i+1]);
  660.         }
  661.         longwrite(hue);
  662.         intwrite(color);
  663.         intwrite(connect);
  664.     }
  665.     for (i=0; i<8; i+=2) ci[i]=(int)column(c[i]);
  666.     for (i=1; i<8; i+=2) ci[i]=(int)row(c[i]);
  667.     for (i=0; i<4; i++) { 
  668.         points[i].x=ci[2*i]; 
  669.         points[i].y=ci[2*i+1]; 
  670.     }
  671.     points[4].x=points[0].x;
  672.     points[4].y=points[0].y;
  673.     sethue(hue,color);
  674. #ifdef WINDOW
  675.     XFillPolygon(display,window,stipplegc,points,4,Complex,CoordModeOrigin);
  676. #endif
  677.     XFillPolygon(display,pixmap,stipplegc,points,4,Complex,CoordModeOrigin);
  678.     if (!connect) return;
  679.     setline(0,line_solid);
  680.     setcolor(1);
  681.     XDrawLines(display,pixmap,gc,points,5,CoordModeOrigin);
  682. #ifdef WINDOW
  683.     XDrawLines(display,window,gc,points,5,CoordModeOrigin);
  684. #endif
  685. }
  686.  
  687. void gbar (double c, double r, double c1, double r1, double hue,
  688.     int color, int connect)
  689. {    
  690.     int x,y,w,h;
  691.     if (fabs(c)>MAXPLOT) return;
  692.     if (fabs(r)>MAXPLOT) return;
  693.     if (fabs(c1)>MAXPLOT) return;
  694.     if (fabs(r1)>MAXPLOT) return;
  695.     x=(int)column(c); y=(int)row(r);
  696.     w=(int)column(c1)-x; h=(int)row(r1)-y;
  697.     if (w<=0) w=1;
  698.     if (h<=0) h=1;
  699.     if (metafile)
  700.     {    
  701.         intwrite(8);
  702.         longwrite(c); longwrite(r);
  703.         longwrite(c1); longwrite(r1);
  704.         longwrite(hue);
  705.         intwrite(color);
  706.         intwrite(connect);
  707.     }
  708.     sethue(hue,color);
  709. #ifdef WINDOW
  710.     XFillRectangle(display,window,stipplegc,x,y,w,h);
  711. #endif
  712.     XFillRectangle(display,pixmap,stipplegc,x,y,w,h);
  713.     if (!connect) return;
  714.     setline(0,line_solid);
  715.     setcolor(1);
  716.     XDrawRectangle(display,pixmap,gc,x,y,w,h);
  717. #ifdef WINDOW
  718.     XDrawRectangle(display,window,gc,x,y,w,h);
  719. #endif
  720. }
  721.  
  722. void gtext (double c, double r, char *text, int color, int centered)
  723. /***** gtext
  724.     output a graphic text on screen.
  725. *****/
  726. {    
  727.     int width;
  728.     if (metafile)
  729.     {    
  730.         intwrite(4); 
  731.         longwrite(c);
  732.         longwrite(r); 
  733.         intwrite(color); 
  734.         intwrite(centered);
  735.         stringwrite(text);
  736.     }
  737.     setcolor(color);
  738.     if (!centered)
  739.     {    
  740. #ifdef WINDOW
  741.         XDrawString(display,window,gc,
  742.             column(c),row(r)+font->ascent,text,strlen(text));
  743. #endif
  744.         XDrawString(display,pixmap,gc,
  745.             column(c),row(r)+font->ascent,text,strlen(text));
  746.     }
  747.     else if (centered==1)
  748.     {    
  749.         width=XTextWidth(font,text,strlen(text));
  750. #ifdef WINDOW
  751.         XDrawString(display,window,gc,
  752.             column(c)-width/2,row(r)+font->ascent,
  753.             text,strlen(text));
  754. #endif
  755.         XDrawString(display,pixmap,gc,
  756.             column(c)-width/2,row(r)+font->ascent,
  757.             text,strlen(text));
  758.     }
  759.     else if (centered==2)
  760.     {    
  761.         width=XTextWidth(font,text,strlen(text));
  762. #ifdef WINDOW
  763.         XDrawString(display,window,gc,
  764.             column(c)-width,row(r)+font->ascent,
  765.             text,strlen(text));
  766. #endif
  767.         XDrawString(display,pixmap,gc,
  768.             column(c)-width,row(r)+font->ascent,
  769.             text,strlen(text));
  770.     }
  771. }
  772.  
  773. void scale (double s)
  774. /***** scale
  775.     scale the screen according s = true width / true height.
  776. *****/
  777. {    
  778.     if (metafile)
  779.     {    
  780.         intwrite(5);
  781.         intwrite((int)(s*1000));
  782.     }
  783. }
  784.  
  785. void translate (XKeyEvent *event, int *key, int *scan);
  786. void mouse (int *x, int *y)
  787. /****** mouse
  788.     wait, until the user marked a screen point with the mouse.
  789. ******/
  790. {    
  791.     XEvent event;
  792.     int taste,scan;
  793.     while (1)
  794.     {
  795.         XWindowEvent(display,window,mask,&event);
  796.         if (event.type==ButtonPress)
  797.         {    
  798.             *x=(int)((event.xkey.x)*1024.0/wscreen);
  799.             *y=(int)((event.xkey.y)*1024.0/hscreen);
  800.             return;
  801.         }
  802.         else if (event.type==KeyPress)
  803.         {
  804.             translate(&(event.xkey),&taste,&scan);
  805.             if (scan==escape)
  806.             {
  807.                 error=1; return;
  808.             }
  809.         }
  810.     }
  811. }
  812.  
  813. void getpixel (double *x, double *y)
  814. {    *x=1024.0/wscreen;
  815.     *y=1024.0/hscreen;
  816. }
  817.  
  818. /********************* text cursor ******************/
  819.  
  820. /* defined as macros */
  821.  
  822. /************** text screen **************************/
  823.  
  824. void show_cursor (void)
  825. {
  826.     char cstring[]=" ";
  827.     if (!cursoron || cx>linelength) return;
  828.     cstring[0]=textend[cx];
  829.     if (cstring[0]==0) cstring[0]=' ';
  830.     XDrawImageString(display,window,invtextgc,
  831.         textoffset+cx*textwidth,
  832.         cy*textheight+textfont->ascent+textoffset,
  833.         cstring,1);
  834. }
  835.  
  836. void hide_cursor (void)
  837. {
  838.     char cstring[]=" ";
  839.     if (!cursoron || cx>linelength) return;
  840.     cstring[0]=textend[cx];
  841.     if (cstring[0]==0) cstring[0]=' ';
  842.     XDrawImageString(display,window,textgc,
  843.         textoffset+cx*textwidth,
  844.         cy*textheight+textfont->ascent+textoffset,
  845.         cstring,1);
  846. }
  847.  
  848. void move_cl (void)
  849. {
  850.     if (cx>0)
  851.     {
  852.         hide_cursor(); cx--; show_cursor();
  853.     }
  854. }
  855.  
  856. void move_cr (void)
  857. {
  858.         hide_cursor(); cx++; show_cursor();
  859. }
  860.  
  861. void cursor_on (void)
  862. {
  863.     if (scrolled) return;
  864.     cursoron=1;
  865.     show_cursor();
  866. }
  867.  
  868. void cursor_off (void)
  869. {
  870.     if (scrolled) return;
  871.     cursoron=0;
  872.     hide_cursor();
  873. }
  874.  
  875. void textline (char *p, int x, int y)
  876. {
  877.     XDrawImageString(display,window,textgc,textoffset+x*textwidth,
  878.         y*textheight+textfont->ascent+textoffset,p+x,
  879.         strlen(p+x));
  880.     if (y==cy && !scrolled) show_cursor();
  881. }
  882.  
  883. void clearline (char *p, int cx, int cy)
  884. {
  885.     XFillRectangle(display,window,invtextgc,
  886.         textoffset+cx*textwidth,textoffset+cy*textheight,
  887.         wscreen-(textoffset+cx*textwidth),textheight);
  888.     memset(p+cx,0,textstart+TEXTSIZE-(p+cx));
  889.     if (!scrolled) show_cursor();
  890. }
  891.  
  892. void clear_eol (void)
  893. {    clearline(textend,cx,cy);
  894. }
  895.  
  896. void clear_screen (void)
  897. {    XFillRectangle(display,window,invtextgc,0,0,wscreen,hscreen);
  898.     cx=0; cy=0; scrolled=0;
  899.     textwindow=textend=textstart;
  900.     memset(textstart,0,TEXTSIZE);
  901. }
  902.  
  903. void textupdate (void)
  904. {    char *tp;
  905.     int i;
  906.     XFillRectangle(display,window,invtextgc,0,0,wscreen,hscreen);
  907.     tp=textwindow; i=0;
  908.     while (tp<=textend && i<maxlines)
  909.     {    textline(tp,0,i);
  910.         i++; tp+=strlen(tp)+1;
  911.     }
  912.     XFlush(display);
  913. }
  914.  
  915. void new_line (void)
  916. {    int length;
  917.     char *tp;
  918.     hide_cursor();
  919.     cy++; cx=0;
  920.     textend+=strlen(textend)+1;
  921.     if (textend>textstart+TEXTSIZE-256)
  922.     {    tp=textstart+(TEXTSIZE-256)/8;
  923.         tp+=strlen(tp)+1;
  924.         memmove(textstart,tp,textend-tp);
  925.         length=tp-textstart;
  926.         textend-=length; textwindow-=length;
  927.     }
  928.     if (cy>=maxlines)
  929.     {    cy--; textwindow+=strlen(textwindow)+1;
  930.         XCopyArea(display,window,window,gc,
  931.             0,textoffset+textheight,
  932.             wscreen,
  933.             (maxlines-1)*textheight,
  934.             0,textoffset);
  935.         clearline(textend,0,cy);
  936.     }
  937. }
  938.  
  939. void gprint (char *s)
  940. /* print a line onto the screen, parse tabs and \nl */
  941. {
  942.     int cx0=cx,cx1,i;
  943.     if (scrolled)
  944.     {    textwindow=oldtextwindow;
  945.         show_cursor();
  946.         scrolled=0;
  947.         refresh_window();
  948.     }
  949.     while (*s)
  950.     {
  951.         switch(*s)
  952.         {
  953.             case 10 : s++; textline(textend,cx0,cy); cx0=0;
  954.                 new_line(); break;
  955.             case 9 :
  956.                 cx1=(cx/4+1)*4;
  957.                 for (i=cx; i<cx1; i++) textend[i]=' ';
  958.                 cx=cx1; s++;
  959.                 break;
  960.             default :
  961.                 textend[cx]=*s; cx++;
  962.                 s++;
  963.                 break;
  964.         }
  965.         if (textend+cx>textstart+TEXTSIZE)
  966.         {    cx0=0; new_line(); }
  967.     }
  968.     textline(textend,cx0,cy);
  969.     XFlush(display);
  970. }
  971.  
  972. /**************** refresh routine **********************/
  973.  
  974. void refresh_window (void)
  975. /* refresh the screen */
  976. {
  977.     if (in_text) textupdate();
  978.     else
  979.     {
  980.         XCopyArea(display,pixmap,window,gc,0,0,wscreen,hscreen,0,0);
  981.         XFlush(display);
  982.     }
  983. }
  984.  
  985. /******************** keyboard and other events **********************/
  986.  
  987. int isgerman (KeySym k)
  988. {    
  989.     if (k=='ä' || k=='ö' || k=='ü' || k=='β' ||
  990.         k=='Ä' || k=='Ö' || k=='Ü') return 1;
  991.     return 0;
  992. }
  993.  
  994. void translate (XKeyEvent *event, int *key, int *scan)
  995. /* Translate events into key codes */
  996. {
  997.     int length,i;
  998.     char buffer[65];
  999.     KeySym keysym;
  1000.     XComposeStatus status;
  1001.  
  1002.     *scan=0; *key=0;
  1003.     length=XLookupString(event,buffer,64,&keysym,&status);
  1004.     switch (keysym)
  1005.     {    case XK_Prior :
  1006.             if (!in_text || textwindow==textstart) break;
  1007.             if (!scrolled)
  1008.             {    oldtextwindow=textwindow;
  1009.                 scrolled=1;
  1010.             }
  1011.             for (i=0; i<maxlines-1; i++)
  1012.             {    textwindow--;
  1013.                 while (textwindow>textstart)
  1014.                 {    if (*(textwindow-1)==0) break;
  1015.                     textwindow--;
  1016.                 }
  1017.                 if (textwindow==textstart) break;
  1018.             }
  1019.             hide_cursor();
  1020.             refresh_window();
  1021.             return;
  1022.         case XK_Next :
  1023.             if (!scrolled || !in_text) break;
  1024.             for (i=0; i<maxlines-1; i++)
  1025.             {    textwindow+=strlen(textwindow)+1;
  1026.                 if (textwindow>=oldtextwindow) break;
  1027.             }
  1028.             if (textwindow>=oldtextwindow)
  1029.             {    textwindow=oldtextwindow;
  1030.                 scrolled=0;
  1031.                 show_cursor();
  1032.             }
  1033.             refresh_window();
  1034.             return;
  1035.     }
  1036.     if (
  1037.         ( ((keysym>=' ') && (keysym<='~')) || isgerman(keysym) )
  1038.         && length>0)
  1039.     {
  1040.         *key=buffer[0];
  1041.         return;
  1042.     }
  1043.     switch (keysym)
  1044.     {
  1045.         case XK_Return : *scan=enter; break;
  1046.         case XK_Escape : *scan=escape; break;
  1047.         case XK_BackSpace : *scan=backspace; break;
  1048.         case XK_Delete : *scan=delete; break;
  1049.         case XK_Up :
  1050.             if (event->state & ControlMask) *scan=clear_home;
  1051.             else *scan=cursor_up ;
  1052.             break;
  1053.         case XK_Down :
  1054.             if (event->state & ControlMask) *scan=clear_home;
  1055.             else *scan=cursor_down; 
  1056.             break;
  1057.         case XK_Right :
  1058.             if (event->state & ShiftMask) *scan=line_end;
  1059.             else if (event->state & ControlMask) *scan=word_right;
  1060.             else *scan=cursor_right; 
  1061.             break;
  1062.         case XK_Left :
  1063.             if (event->state & ShiftMask) *scan=line_start;
  1064.             else if (event->state & ControlMask) *scan=word_left;                         else *scan=cursor_left;
  1065.             break;
  1066.         case XK_Insert : *scan=help; break;
  1067.         case XK_F1 : *scan=fk1; break;
  1068.         case XK_F2 : *scan=fk2; break;
  1069.         case XK_F3 : *scan=fk3; break;
  1070.         case XK_F4 : *scan=fk4; break;
  1071.         case XK_F5 : *scan=fk5; break;
  1072.         case XK_F6 : *scan=fk6; break;
  1073.         case XK_F7 : *scan=fk7; break;
  1074.         case XK_F8 : *scan=fk8; break;
  1075.         case XK_F9 : *scan=fk9; break;
  1076.         case XK_F10 : *scan=fk10; break;
  1077.         case XK_KP_Enter : *scan=enter; break;
  1078.         case XK_Tab : *scan=switch_screen; break;
  1079.         case XK_End :
  1080.             if (event->state & ShiftMask) *scan=clear_home;
  1081.             else if (event->state & ControlMask) *scan=clear_home;
  1082.             else *scan=line_end;
  1083.             break;
  1084.         case XK_Begin :
  1085.             if (event->state & ShiftMask) *scan=clear_home;
  1086.             else if (event->state & ControlMask) *scan=clear_home;
  1087.             else *scan=line_start;
  1088.             break;
  1089.     }
  1090. }
  1091.  
  1092. void process_event (XEvent *event)
  1093. {
  1094.     XEvent dummyevent;
  1095.     switch (event->type)
  1096.     {
  1097.         case GraphicsExpose:
  1098.             if (event->xgraphicsexpose.count>0) break;
  1099.             refresh_window(); break;
  1100.         case Expose:
  1101.             if (event->xexpose.count>0) break;
  1102.             refresh_window(); break;
  1103.         case ConfigureNotify :
  1104.             while (XCheckWindowEvent(display,window,mask,&dummyevent));
  1105.             if (event->xconfigure.width==wscreen &&
  1106.                 event->xconfigure.height==hscreen) break;
  1107.             wscreen=event->xconfigure.width;
  1108.             hscreen=event->xconfigure.height;
  1109.             computechar();
  1110.             computetext();
  1111.             XFreePixmap(display,pixmap);
  1112.             pixmap=XCreatePixmap(display,window,
  1113.                 wscreen,hscreen,depth);
  1114.             clear_graphics();
  1115.             textwindow=textend-1;
  1116.             while (textwindow>=textstart && *textwindow) textwindow--;
  1117.             textwindow++; oldtextwindow=textwindow; cy=0;
  1118.             scrolled=0; cursoron=1;
  1119.             refresh_window();
  1120.             break;
  1121.         case DestroyNotify :
  1122.             exit(1); break;
  1123.     }
  1124. }
  1125.  
  1126. int wait_key (int *scan)
  1127. /***** 
  1128.     wait for a keystroke. return the scancode.
  1129. *****/
  1130. {   
  1131.     int taste;
  1132.     XEvent event;
  1133.  
  1134.     *scan=key_none; taste=0;
  1135.     while (1)
  1136.     {
  1137.         XWindowEvent(display,window,mask,&event);
  1138.         if (event.type==KeyPress)
  1139.         {    translate(&(event.xkey),&taste,scan);
  1140.             if (*scan || taste) break;
  1141.         }
  1142.         process_event(&event);
  1143.     }
  1144.     return taste;
  1145. }
  1146.  
  1147. int test_key (void)
  1148. /***** test_key
  1149.     see, if user pressed the keyboard.
  1150.     return the scan_code, if he did.
  1151. *****/
  1152. {   
  1153.     XEvent event;
  1154.     int scan,key;
  1155.     if (userbreak)
  1156.     {
  1157.         userbreak=0; return escape;
  1158.     }
  1159.     else if (
  1160.         XCheckWindowEvent(display,window,mask,&event))
  1161.     {
  1162.         if (event.type==KeyPress)
  1163.         {    translate(&(event.xkey),&key,&scan);
  1164.             return scan;
  1165.         }
  1166.         else process_event(&event);
  1167.     }
  1168.     return 0;
  1169. }
  1170.  
  1171. /**************** directory *******************/
  1172.  
  1173. char path[256];
  1174.  
  1175. char *cd (char *dir)
  1176. /* sets the path if dir!=0 and returns the path */
  1177. {    
  1178.     chdir(dir);
  1179.     if (getcwd(path,256)) return path;
  1180.     return dir;
  1181. }
  1182.  
  1183. char *dir (char *pattern)
  1184. /* if pattern==0, find next file, else find pattern.
  1185.    return 0, if there is no file.
  1186. */
  1187. {    return 0;
  1188. }
  1189.  
  1190. /***************** clear screens ********************/
  1191.  
  1192. void clear_graphics (void)
  1193. {    
  1194.     XFillRectangle(display,pixmap,cleargc,0,0,wscreen,hscreen);
  1195. #ifdef WINDOW
  1196.     XFillRectangle(display,window,cleargc,0,0,wscreen,hscreen);
  1197. #endif
  1198.     XFlush(display);
  1199. }
  1200.  
  1201. int execute (char *name, char *args)
  1202. /**** execute
  1203.     call an external program, return 0, if there was no error.
  1204. ****/
  1205. {    return 0;
  1206. }
  1207.  
  1208. void gflush (void)
  1209. {
  1210. #ifndef WINDOW
  1211.     XCopyArea(display,pixmap,window,gc,0,0,wscreen,hscreen,0,0);
  1212. #endif
  1213.     XFlush(display);
  1214. }
  1215.  
  1216. #ifndef SY_CLK_TCK
  1217. #define SY_CLK_TCK 50
  1218. #endif
  1219.  
  1220. double myclock (void)
  1221. /* Return the time in seconds */
  1222. {
  1223. #ifdef RS6000
  1224.     struct timestruc_t t;
  1225.     gettimer(TIMEOFDAY,&t);
  1226.     return (t.tv_sec+t.tv_nsec/1000000000.0);
  1227. #else
  1228.     struct tms b;
  1229.     times(&b);
  1230.     return (double)(b.tms_utime)/(SY_CLK_TCK);
  1231. #endif
  1232. }
  1233.  
  1234. void edit_on (void)
  1235. {
  1236. }
  1237.  
  1238. void edit_off (void)
  1239. {
  1240. }
  1241.  
  1242. void sys_wait (double time, int *scan)
  1243. {    double now;
  1244.     XSync(display,0);
  1245.     now=myclock();
  1246.     while (myclock()<now+time)
  1247.     {    *scan=test_key();
  1248.         if (*scan==switch_screen)
  1249.         {    if (in_text)
  1250.             {    graphic_mode();
  1251.                 wait_key(scan);
  1252.                 text_mode();
  1253.             }
  1254.             else
  1255.             {    text_mode();
  1256.                 wait_key(scan);
  1257.                 graphic_mode();
  1258.             }
  1259.             *scan=0;
  1260.         }
  1261.         if (*scan==escape || *scan==enter) return;
  1262.     }
  1263.     *scan=0;
  1264. }
  1265.  
  1266. /************ main *******************/
  1267.  
  1268. void usage (void)
  1269. {
  1270.     fprintf(stderr,"euler [-f FONT] [-g FONT] [-s KBYTES]\n"
  1271.         " [-geom GEOMETRY] [-d DISPLAY] [-0..15 COLOR] files\n");
  1272. }
  1273.  
  1274. void get_geometry (char *s)
  1275. {
  1276.     long d;
  1277.     char *end;
  1278.     d=strtol(s,&end,10);
  1279.     if (!end || end==s) return; else { userwidth=d; s=end; }
  1280.     if (*s++!='x') { usage(); exit(1); }
  1281.     d=strtol(s,&end,10);
  1282.     if (!end || end==s) return; else { userheight=d; s=end; }
  1283.     usersize=1;
  1284.     if (*s==0) return;
  1285.     d=strtol(s,&end,10);
  1286.     if (!end || end==s) return; 
  1287.     else 
  1288.     { 
  1289.         userx=d;
  1290.         if (*s=='-' && d==0) userx=-1;
  1291.         s=end; 
  1292.     }
  1293.     userpos=1;
  1294.     if (*s==0) return;
  1295.     d=strtol(s,&end,10);
  1296.     if (!end || end==s) return;
  1297.     else 
  1298.     { 
  1299.         usery=d;
  1300.         if (*s=='-' && d==0) usery=-1;
  1301.         s=end; 
  1302.     }
  1303. }
  1304.  
  1305. void setint (int code)
  1306. {       
  1307.     userbreak=1;
  1308.     signal(SIGTERM,setint);
  1309. }
  1310.  
  1311. #ifdef FPE
  1312.  
  1313. void setfpe (int code)
  1314. {       
  1315.     error=1;
  1316.     signal(SIGFPE,setfpe);
  1317. }
  1318.  
  1319. #endif
  1320.  
  1321. int ioerrorhandler (Display *display)
  1322. {    exit(1)    ;
  1323.     return 0;
  1324. }
  1325.  
  1326. int main (int argc, char *argv[])
  1327. {
  1328.     XEvent event;
  1329.     int nn;
  1330.     /* init GEM */
  1331.     signal(SIGINT,setint);
  1332. #ifdef FPE
  1333.     signal(SIGFPE,setfpe);
  1334. #endif
  1335.     XSetIOErrorHandler(ioerrorhandler);
  1336.     nextcheck=myclock();
  1337.     while (argc>1)
  1338.     {
  1339.         if (argv[1][0]=='=')
  1340.         {    get_geometry(argv[1]+1);
  1341.             argc--; argv++;
  1342.         }
  1343.         else if (argv[1][0]=='-')
  1344.         {
  1345.             switch(argv[1][1])
  1346.             {
  1347.                 case 'f' :
  1348.                     if (argv[1][2])
  1349.                     {    strcpy(textfontname,argv[1]+2); break;
  1350.                     }
  1351.                     else if (argv[2])
  1352.                     {    strcpy(textfontname,argv[2]); argc--; argv++;
  1353.                         break;
  1354.                     }
  1355.                     break;
  1356.                 case 'g' :
  1357.                     if (strncmp(argv[1],"-geom",5)==0)
  1358.                     {    if (argv[2])
  1359.                         {    get_geometry(argv[2]); argc--; argv++;
  1360.                         }
  1361.                     }
  1362.                     else if (argv[1][2])
  1363.                     {    strcpy(fontname,argv[1]+2); break;
  1364.                     }
  1365.                     else if (argv[2])
  1366.                     {    strcpy(fontname,argv[2]); argc--; argv++;
  1367.                         break;
  1368.                     }
  1369.                     break;
  1370.                 case 's' : 
  1371.                     if (argv[1][2])
  1372.                     {    memsize=atoi(argv[1]+2)*1024l; break;
  1373.                     }
  1374.                     else if (argv[2])
  1375.                     {    memsize=atoi(argv[2])*1024l; argc--; argv++;
  1376.                         break;
  1377.                     }
  1378.                     break;
  1379.                 case 'd' :
  1380.                     strcpy(sdisp,argv[2]); argc--; argv++; break;
  1381.                 default :
  1382.                     if (sscanf(argv[1]+1,"%d",&nn)==1 && nn>=0 && nn<maxcolors)
  1383.                     {    colorname[nn]=argv[2]; argc--; argv++;
  1384.                         break;
  1385.                     }
  1386.                     usage(); exit(1);
  1387.             }
  1388.             argc--; argv++;
  1389.         }
  1390.         else break;
  1391.     }
  1392.     if (!memory_init()) exit(1);
  1393.     grafik();
  1394.     XWindowEvent(display,window,ExposureMask,&event);
  1395.     process_event(&event);
  1396.     main_loop(argc,argv);
  1397.     return 0;
  1398. }
  1399.  
  1400. xə⌐⇧F✓EULER881PRJ &¢[ə¼⇧❎⇩EXPRESS C   ²½yə¡⇧gåEXTEND  C   Ätxəנ⇧!FUNCS   C   ódìəת⇧⓪¡FUNCS   H   ùñR⑥⇨⇩⑥⇦GRAPHICSC   bWÉə❎⇩טGRAPHICSH   4`x⑦%⇩,⇨HEADER  H   ə¼yə&⇩q③ar;
  1401.             p[6]=p[2]; p[7]=p[3]-gl_hchar;
  1402.             vro_cpyfm(handle,3,p,&mfdb1,&mfdb1);
  1403.             b[0]=htext;
  1404.             b[1]=vtext+(maxlines-1)*gl_hchar;
  1405.             b[2]=b[0]+linelength*gl_wchar;
  1406.             b[3]=b[1]+gl_hchar;
  1407.             tlp=textend; tlx=0; tly=cy; do_clearline(b);
  1408.             if (editor)
  1409.             {    wind_update(END_UPDATE);
  1410.                 graf_mouse(M_ON,0);
  1411.             }
  1412.         }
  1413.         else
  1414.         {    textupdate();
  1415.             clearline(textend,0,cy);
  1416.         }
  1417.         set_slide();
  1418.     }
  1419.     if (con) show_cursor();
  1420. }
  1421.  
  1422. void gprint (char *s)
  1423. /* print a line onto the screen, parse tabs and \nl              next+=n;
  1424.                        memmove(p,(char *)(&x),sizeof(double));
  1425.                        p+=sizeof(double);
  1426.                    }
  1427.             }
  1428.             else if (isalpha(*next) &&
  1429.                 (next==firstchar || !isalpha(*(next-1))) &&
  1430.                 (com=preview_command(&l))!=0)
  1431.             /* Try to find a builtin command */
  1432.             {    
  1433.                 if ((p-(char *)result)%2==0) *p++=' ';
  1434.                 *p++=3;
  1435.                 memmove(p,(char *)(&com),sizeof(commandtyp *));
  1436.                 p+=sizeof(commandtyp *);
  1437.                 next+=l;
  1438.             }
  1439.             else if (*next=='.' && *(next+1)=='.')
  1440.             {    *p++=' '; next_line(); firstchar=next;
  1441.             }
  1442.             else *p++=*next++;
  1443.         }
  1444.         else { *p++=0; next_line(); firstchar=next; }
  1445.         if (p>=ramend-80)
  1446.         {    output("Memory overflow!\n"); error=210; goto stop;
  1447.         }
  1448.     }
  1449.     stop:
  1450.     udf=0; if (error) return;
  1451.     result->size=((p-(char *)result)/2+1)*2;
  1452. #ifdef SPECIAL_ALIGNMENT
  1453.     result->size=((result->size-1)/8+1)*8;
  1454. #endif
  1455.     newram=(char *)result+result->size;
  1456.     assign(var,result);
  1457.     aborted:
  1458.     udf=0;
  1459. }
  1460.  
  1461. void do_return (void)
  1462. {    if (!udfon)
  1463.     {    output("No user defined function active!\n");
  1464.         error=56; return;
  1465.     }
  1466.     else udfon=2;
  1467. }
  1468.  
  1469. void do_break (void)
  1470. {    if (!udfon)
  1471.     {    output("End only allowed in functions!\n"); error=57;
  1472.     }
  1473. }
  1474.  
  1475. void do_for (void)
  1476. /***** do_for
  1477.     do a for command in a UDF.
  1478.     for i=value to value step value; .... ; end
  1479. *****/
  1480. {    int h,signum;
  1481.     char name[16],*jump;
  1482.     header *hd,*init,*end,*step;
  1483.     double vend,vstep;
  1484.     struct { header hd; double value; } rv;
  1485.     if (!udfon)
  1486.     {    output("For only allowed in functions!\n"); error=57; return;
  1487.     }
  1488.     rv.hd.type=s_real; *rv.hd.name=0;
  1489.     rv.hd.size=sizeof(header)+sizeof(double); rv.value=0.0;
  1490.     scan_space(); scan_name(name); if (error) return;
  1491.     kill_local(name);
  1492.     newram=endlocal;
  1493.     hd=new_reference(&rv.hd,name); if (error) return;
  1494.     endlocal=newram=(char *)hd+hd->size;
  1495.     scan_space(); if (*next!='=')
  1496.     {    output("Syntax error in for.\n"); error=71; goto end;
  1497.     }
  1498.     next++; init=scan(); if (error) goto end;
  1499.     init=getvalue(init); if (error) goto end;
  1500.     if (init->type!=s_real)
  1501.     {    output("Startvalue must be real!\n"); error=72; goto end;
  1502.     }
  1503.     rv.value=*realof(init);
  1504.     scan_space(); if (strncmp(next,"to",2))
  1505.     {    output("Endvalue missing in for!\n"); error=73; goto end;
  1506.     }
  1507.     next+=2;
  1508.     end=scan(); if (error) goto end;
  1509.     end=getvalue(end); if (error) goto end;
  1510.     if (end->type!=s_real)
  1511.     {    output("Endvalue must be real!\n"); error=73; goto end;
  1512.     }
  1513.     vend=*realof(end);
  1514.     scan_space(); 
  1515.     if (!strncmp(next,"step",4))
  1516.     {    next+=4;
  1517.         step=scan(); if (error) goto end;
  1518.         step=getvalue(step); if (error) goto end;
  1519.         if (step->type!=s_real)
  1520.         {    output("Stepvalue must be real!\n"); error=73; goto end;
  1521.         }
  1522.         vstep=*realof(step);
  1523.     }
  1524.     else vstep=1.0;
  1525.     signum=(vstep>0);
  1526.     if (signum && rv.value>vend) { scan_end(); goto end; }
  1527.     else if (!signum && rv.value<vend) { scan_end(); goto end; }
  1528.     newram=endlocal;
  1529.     scan_space(); if (*next==';' || *next==',') next++;
  1530.     jump=next;
  1531.     vend=vend+epsilon*vstep;
  1532.     while (!error)
  1533.     {    if (*next==1)
  1534.         {    output("End missing!\n");
  1535.             error=401; goto end;
  1536.         }
  1537.         h=command();
  1538.         if (h==c_return) break;
  1539.         if (h==c_break) { scan_end(); break; }
  1540.         if (h==c_end)
  1541.         {    rv.value+=vstep;
  1542.             if (signum==1 && rv.value>vend) break;
  1543.             else if (!signum && rv.value<vend) break;
  1544.             else next=jump;
  1545.             if (test_key()==escape) { error=1; break; }
  1546.         }
  1547.     }
  1548.     end : kill_local(name);
  1549. }
  1550.  
  1551. void do_loop (void)
  1552. /***** do_loop
  1553.     do a loop command in a UDF.
  1554.     loop value to value; .... ; end
  1555. *****/
  1556. {    int h;
  1557.     char *jump;
  1558.     header *init,*end;
  1559.     long vend,oldindex;
  1560.     if (!udfon)
  1561.     {    output("Loop only allowed in functions!\n"); error=57; return;
  1562.     }
  1563.     init=scan(); if (error) return;
  1564.     init=getvalue(init); if (error) return;
  1565.     if (init->type!=s_real)
  1566.     {    output("Startvalue must be real!\n"); error=72; return;
  1567.     }
  1568.     oldindex=loopindex;
  1569.     loopindex=(long)*realof(init);
  1570.     scan_space(); if (strncmp(next,"to",2))
  1571.     {    output("Endvalue missing in for!\n"); error=73; goto end;
  1572.     }
  1573.     next+=2;
  1574.     end=scan(); if (error) goto end;
  1575.     end=getvalue(end); if (error) goto end;
  1576.     if (end->type!=s_real)
  1577.     {    output("Endvalue must be real!\n"); error=73; goto end;
  1578.     }
  1579.     vend=(long)*realof(end);
  1580.     if (loopindex>vend) { scan_end(); goto end; }
  1581.     newram=endlocal;
  1582.     scan_space(); if (*next==';' || *next==',') next++;
  1583.     jump=next;
  1584.     while (!error)
  1585.     {    if (*next==1)
  1586.         {    output("End missing!\n");
  1587.             error=401; goto end;
  1588.         }
  1589.         h=command();
  1590.         if (h==c_return) break;
  1591.         if (h==c_break) { scan_end(); break; }
  1592.         if (h==c_end)
  1593.         {    loopindex++;
  1594.             if (loopindex>vend) break;
  1595.             else next=jump;
  1596.             if (test_key()==escape) { error=1; break; }
  1597.         }
  1598.     }
  1599.     end : loopindex=oldindex;
  1600. }
  1601.  
  1602. void do_repeat (void)
  1603. /***** do_loop
  1604.     do a loop command in a UDF.
  1605.     for value to value; .... ; endfor
  1606. *****/
  1607. {    int h;
  1608.     char *jump;
  1609.     if (!udfon)
  1610.     {    output("Loop only allowed in functions!\n"); error=57; return;
  1611.     }
  1612.     newram=endlocal;
  1613.     scan_space(); if (*next==';' || *next==',') next++;
  1614.     jump=next;
  1615.     while (!error)
  1616.     {    if (*next==1)
  1617.         {    output("End missing!\n");
  1618.             error=401; break;
  1619.         }
  1620.         h=command();
  1621.         if (h==c_return) break;
  1622.         if (h==c_break) { scan_end(); break; }
  1623.         if (h==c_end)
  1624.         {    next=jump;
  1625.             if (test_key()==escape) { error=1; break; }
  1626.         }
  1627.     }
  1628. }
  1629.  
  1630. void do_end (void)
  1631. {    if (!udfon)
  1632.     {    output("End only allowed in functions!\n"); error=57;
  1633.     }
  1634. }
  1635.  
  1636. void do_else (void)
  1637. {    if (!udfon)
  1638.     {    output("Else only allowed in functions!\n"); error=57; return;
  1639.     }
  1640.     scan_endif();
  1641. }
  1642.  
  1643. void do_endif (void)
  1644. {    if (!udfon)
  1645.     {    output("Endif only allowed in functions!\n