/*
 Copyright (c) Andrew Wuensche
 
 This file is part of DDLab (Discrete Dynamics Lab) <www.ddlab.org>
 
 DDLab is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with DDLab.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "edecfunc.h"
#ifdef __DARWIN__
  #include <sys/stat.h>
#endif

/*note: 3 alternative graphics files, UNIX, WATCOM and Borlandc*/

/*-------------------- UNIX graphics -----------------------------*/
# if __UNIX__

#include <sys/types.h>

#define MaxOf(a, b)  (a > b) ? a : b
#define MinOf(a, b)  (a < b) ? a : b

/***************  list of functions in this file *************/
/*void getimage(int x, int y, int x1, int y1, Pixmap *image)*/
/*void putimage(int x, int y, Pixmap *image, 
                         int drawing_mode, char *which_image)*/
/*void copy_part_image(Drawable *source_d, Drawable *dest_d,
			int source_x, int source_y,
			int dest_x, int dest_y,
			int width, int height)*/
/*void freeimage(Pixmap *image)*/     
void subsec_delay(long microsec);
/*void print_out(char *array)*/
/*signed int vgax(signed int xcoord)*/
/*signed int vgay(signed int ycoord)*/
/*void moveto(signed int xpos, signed int ypos)*/
/*void moverel(signed int xpos, signed int ypos)*/
/*signed int textwidth(char *textbuf)*/
/*signed int text_pix_width(char *textbuf)*/
/*signed int textheight(char *textbuf)*/
/*void outtext(char *textbuf)*/
/*void setcolor(unsigned char thiscolor)*/
/*unsigned char getcolor(void)*/
/*void putpixel(signed int xpos, signed int ypos,unsigned char color)*/
/*void setviewport(signed int left,signed int top, 
    signed int right, signed int bottom, signed int clip)*/
/*void clearviewport(void)*/
/*void linerel(signed int dx,signed int dy)*/
/*void lineto(signed int x,signed int y)*/
/*void setfillstyle(signed int pattern, signed int color)*/
/*void bar(signed int a,signed int b,signed int a1,signed int b1)*/
/*void bar3d(signed int a,signed int b,
    signed int a1,signed int b1,
      signed int dummy1,signed int dummy2)*/
/*void fillpoly(signed int numpoints,int polypoints[])*/
/*void pieslice(char pi_outline,signed int x,signed int y,
          signed int s_angle,signed int e_angle,signed int radius)*/
/*signed int getmaxx(void)*/
/*signed int getmaxy(void)*/
/*unsigned long getpixel(signed int x,signed int y)*/
/*void printimage(void)*/
/*unsigned long filelength(signed int fid)*/

/*void open_graphics(char firstgraphics, char sei)*/

void setup_images(void);
void free_images(void);
/*void close_graphics(void)*/
/*char resize_window(void)*/
/*void setup_fonts(signed int p_size);*/
/*void free_fonts(void)*/
/*void revise_graphics(void)*/
void setup_colors(void);
void show_all_colors(void);
/*void show_old_colors(void)*/

char CHeight_changed=0;
     
/*******************  put an image ***********/
void getimage(int x, int y, int x1, int y1, 
                                      Pixmap *image){
    /*First, create the pixmap*/
    *image = XCreatePixmap(D,W,x1-x+1,y1-y+1,screen_depth);
	
    if (*image == 0) {
       fprintf(stderr, "%s\n", "Error creating pixmap");
       return;
    }	
    XCopyArea(D,W,*image,Gc,x,y,x1-x+1,y1-y+1,0,0);
}

/*******************  put an image ************/   
void putimage(int x, int y, Pixmap *image,
                  int drawing_mode,char *which_image){
 Window	root_window;
 int	top, left;
 unsigned int	border, depth;
 unsigned int	width, height;
	
    if (*image == 0) {
       fprintf(stderr,"\nZero image passed to putimage - %s", which_image);
       /*input_string(1,0);*/
       return;
    }
    if (XGetGeometry(D,*image, &root_window, 
      &top, &left, &width, &height, &border, &depth) == 0)
		fprintf(stderr, "%s\n",
            "Failed to get Pixmap geometry in putimage");
    XCopyArea(D,*image,*current_draw,Gc,0,0,width,height,x,y);   
}

/******************* put_partial_image ************/
void copy_part_image(Drawable *source_d, Drawable *dest_d,
			int source_x, int source_y,
			int dest_x, int dest_y,
			int width, int height) {

    if (*source_d == 0) {
       fprintf(stderr, "%s \n", "Zero source image in copy_part_image");
       return;
    }		
    if (*dest_d == 0){
         fprintf(stdout,"%s\n","Null pixmap passed to copy_part_image");
	 *dest_d = XCreatePixmap(D,W,width, height,screen_depth);
    }

    XCopyArea(D,*source_d,*dest_d,Gc,
            source_x,source_y,width,height,dest_x,dest_y);
}

/*******************  free an image ************/
void freeimage(Pixmap *image){
	if (*image == 0) {
	   fprintf(stderr,"\n Zero image passed to freeimage");
	   return;
	}
	XFreePixmap(D,*image);
	*image = 0;
}

/*******************  delay for less that one second ************/     
void subsec_delay(long microsec){
  long starttime_m;
  struct timeval tp;
  struct timezone tzp;                   
      
      sprintf(textb[0],"tp");
      sprintf(textb[0],"tzp");

      gettimeofday(&tp,&tzp);
      starttime_m=tp.tv_usec;
      
      while (1){
         gettimeofday(&tp,&tzp);         
         if (starttime_m<tp.tv_usec){  
            if (tp.tv_usec-starttime_m>=microsec) break;
         }
         else if (starttime_m>tp.tv_usec){  
            if ((1000000-starttime_m)+tp.tv_usec>=microsec) break;
         }
      }

}
/**************  print text ****************/
void print_out(char *array){
    fprintf(stderr,"%s",array);
}
/****************** turn vga x coord to general coord *********/ 
signed int vgax(signed int xcoord){
  signed int xdim;
    xdim=(signed int) (xcoord *((float)(Maxx+1)/640));
    if (xdim<1) xdim=1;
    return(xdim);
    /*return((signed int) (xcoord *((float)(Maxx+1)/640)));*/ 
} 
/********* turn vga y coord to general coord*************/ 
signed int vgay(signed int ycoord){
   signed int ydim;
    ydim=(signed int) (ycoord *((float)(WinMaxy+1)/480));
    if (ydim<1) ydim=1;
    return(ydim);
    /*return((signed int) (ycoord *((float)(WinMaxy+1)/480)));*/ 
} 
/********* move the ref coord to new poss ************/
void moveto(signed int xpos, signed int ypos){
   getx=xpos;    
   gety=ypos;
}
/********* move the ref coord a given distance ************/
void moverel(signed int xpos, signed int ypos){
   getx+=xpos;    
   gety+=ypos;
}
/*********** get width of text string *****************/
signed int textwidth(char *textbuf){
     return(strlen(textbuf)*CWidth);        
}
/****** get actual pix length of string, in case prop font char width varies ****/
signed int text_pix_width(char *textbuf){
  signed int textw,texth,thisx,thisy;
     thisx=getx;
     thisy=gety;
     moveto(0,-50);//above visible screen
     outtext(textbuf);
     textw=getx;  //text_pix_length
     moveto(thisx,thisy); //restore position
     return(textw);        
}
/*********** get height of text character**************/
signed int textheight(char *textbuf){
     return(CHeight);        
}
/*********** write text and update ref coords **************/
void outtext(char *textbuf){
  signed int twidth;
   /*if (getcolor()==black) setcolor(white);*/
   moverel(0,CHeight-2);
   XDrawString(D,W,Gc,getx,gety,textbuf,strlen(textbuf));
   /*moverel((strlen(textbuf))*CWidth,-CHeight+2);*/
   if (fonttype==0) twidth=XTextWidth(nonpropfont,textbuf,strlen(textbuf));
   else twidth=XTextWidth(propfont,textbuf,strlen(textbuf));
   if (font_d_m_s=='s') twidth*=.6;
   else if (font_d_m_s=='m') twidth*=.8;
   moverel(twidth,-CHeight+2); 
}

/*********** set the current foreground color **************/
void setcolor(unsigned char thiscolor){
  if (thiscolor>52){
      //fprintf(stderr,"%d ",thiscolor);
      return;
  }    
  XSetForeground(D,Gc,(unsigned long)Color_Table[thiscolor]);
  nowcolor=thiscolor;
}
/*********** get the current foreground color **************/
unsigned char getcolor(void){
   return(nowcolor);
}
		   
/*********** draw single pixel in given color  **************/
void putpixel(signed int xpos, signed int ypos,unsigned char color){
	unsigned char tempcolor;
	
	tempcolor=nowcolor;
	setcolor(color);
	XDrawPoint(D,*current_draw, Gc,xpos,ypos);
	setcolor(tempcolor);         
}

/*********** clip graphics in a rectangle **************/
void setviewport(signed int left,signed int top,
    signed int right, signed int bottom,
                 signed int clip){        
   viewport[0].x=left;
   viewport[0].y=top;
   viewport[0].width=right-left+1;
   viewport[0].height=bottom-top+1;

   XSetClipRectangles(D,Gc,0,0,viewport,1,Unsorted);
   view_x0=left;
   view_y0=top;
   view_x1=right;
   view_y1=bottom;
}

/**** erase viewport, ie fill with background color *****/
void clearviewport(void){
 unsigned char tempcolor; 
   tempcolor=nowcolor;
   setcolor(black);  /*background color*/
   /*draw a filled rectangle as large as the current viewport*/
    XFillRectangle(D,*current_draw,Gc,viewport[0].x,viewport[0].y,
        viewport[0].x+viewport[0].width,viewport[0].y+viewport[0].height);
   setcolor(tempcolor);
}

/* draw line given distance  from ref coords to new coords, update *****/
void linerel(signed int dx,signed int dy){
   line(getx,gety,getx+dx,gety+dy);
   moveto(getx+dx,gety+dy);
} 
/**** draw line from ref coords to new coords, update *****/
void lineto(signed int x,signed int y){
    line(getx,gety,x,y);
    moveto(x,y);
}
/*********** set the fill color and pattern  **************/
void setfillstyle(signed int pattern, signed int color){
   fillcolor=color;
   XSetFillStyle(D,Gc,pattern);
}
/********* draw rectangular colored block, no outline ******/
void bar(signed int a,signed int b,
         signed int a1,signed int b1){
 unsigned char tempcolor;
   tempcolor=nowcolor;
   setcolor(fillcolor);
   XFillRectangle(D,*current_draw,Gc,a,b,a1-a+1,b1-b+1);
   setcolor(tempcolor);
}

/***************** draw filled rectangle *******************/
void bar3d(signed int a,signed int b,
    signed int a1,signed int b1,
      signed int dummy1,signed int dummy2){
  unsigned char tempcolor;
   tempcolor=nowcolor;
   setcolor(fillcolor);

   XFillRectangle(D,*current_draw,Gc,a,b,a1-a+1,b1-b+1);
   setcolor(tempcolor);
   XDrawRectangle(D,*current_draw,Gc,a,b,a1-a,b1-b);
}

/****************** draw filled poly **********************/
void fillpoly(signed int numpoints,signed int polypoints[]){
  unsigned char tempcolor;
  /*XPoint points[numpoints];*/
# if __IRIX__
     XPoint* points= (XPoint*) malloc(numpoints*sizeof(XPoint));
# else
     XPoint points[numpoints];
# endif
  signed int z;
   
   for (z=0;z<=numpoints-1;z++){
        points[z].x=polypoints[z*2];
        points[z].y=polypoints[z*2+1];
   }
   tempcolor=nowcolor;
   setcolor(fillcolor);
   XFillPolygon(D,*current_draw,
           Gc,points,numpoints,Convex,CoordModeOrigin);
   setcolor(tempcolor);
}
/******** draw circle and fill with given color *************/
void pieslice(char pi_outline, signed int x,signed int y,
	  signed int s_angle,signed int e_angle,signed int radius){
  unsigned char tempcolor;
  signed int tempx,tempy;
   
   tempcolor=nowcolor;
   setcolor(fillcolor);
   XFillArc(D,*current_draw,Gc,
            x-radius,y-radius,radius*2,radius*2,s_angle,e_angle*64);
   if (pi_outline==2 && radius>=2){ /*draw black outline if circle>=4 pixels, for 3d iso*/
      setcolor(tempcolor);
      circle(x,y,radius);
   }
   else if (pi_outline==1 && radius>=3){ /*draw contrasting outline if circle>=6 pixels*/
      setcolor(tempcolor);
      circle(x,y,radius);
   }
   setcolor(tempcolor);
}
/******************** window width  *************************/
signed int getmaxx(void){
   return(Maxx);
}
/******************** window height  *************************/
signed int getmaxy(void){
   return(WinMaxy);
}
/********************* get the color of a pixel **************/
unsigned long getpixel(signed int x,signed int y){ 
  XImage *onepixel;	   
    onepixel = XGetImage(D,W,x,y,1,1,AllPlanes,XYPixmap);
    
    if (onepixel != NULL)
    	return(XGetPixel(onepixel,0,0));
    else return(0);
}
/*********************** print the window  ********************/
void printimage(void){
  char 		 cmd[1024];
  char           error = 0;
  unsigned int xbox,boxx,boxy,tempx,tempy;
  Pixmap	 *printbox;

    tempx=getx;
    tempy=gety;
    if ((printbox = (Pixmap *)malloc(sizeof(Pixmap *))) == NULL)
		outof_memory("printbox");	
    *printbox=0;

    boxx=Maxx/2;
    boxy=2;
    getimage(boxx,boxy,Maxx-1,boxy+CHeight*2+vgay(6),printbox);
    xbox=draw_prompt_box(2);
    outtext(
       "save/print: without frame -s/p, with frame -S/P, no greyscale +n");
    moveto(xbox,gety+CHeight);
    outtext(
       "then click left mouse button in window, quit-q:");

    input_string(2,0);
    if (is[0]=='p'|| is[0]=='P' || is[0]=='s'|| is[0]=='S'){
          sprintf(textb[9],"%s","printbox");
          putimage(boxx,boxy,printbox,COPY_PUT,textb[9]);
    }
    else{
	is[0]=0;
        sprintf(textb[9],"%s","printbox");
	putimage(boxx,boxy,printbox,COPY_PUT,textb[9]);		
        freeimage(printbox);
        free(printbox);
	return;
    }
    XFlush(D);
    if (is[0]=='p' || is[0]=='s'){
       XFlush(D);
       sprintf(cmd,"xwd > temp_window_file.im"); /*without frame*/
    }
    else{ 
        XFlush(D);
	sprintf(cmd,"xwd -frame > temp_window_file.im"); /*with frame*/
    }
    vret=system(cmd);
    XFlush(D);

    if (is[1]=='n')  sprintf(cmd, /*without grey scale*/
       "xpr -device ps -compact -cutoff 99 temp_window_file.im > temp_window_file.ps");
    else{
       sprintf(cmd, "xwdtopnm temp_window_file.im | pnmtops > temp_window_file.ps");
       vret=system(cmd);
    }
   
    draw_prompt_box(1);
    outtext(" wait");
    sprintf(textb[9],"%s","printbox");
    putimage(boxx,boxy,printbox,COPY_PUT,textb[9]);

    if (error == 0  ) {
       if (is[0]=='p'|| is[0]=='P'){
	  sprintf(cmd,"lpr temp_window_file.ps");
	  vret=system(cmd);
       }
       draw_prompt_box(1);
       outtext(" done - press any key to continue:");
    } 
    else {
	draw_prompt_box(1);
	outtext(" could not print -- xwdtopnm not found");
    }
    
    input_string(1,0);
    sprintf(textb[9],"%s","printbox");
    putimage(boxx,boxy,printbox,COPY_PUT,textb[9]);
    freeimage(printbox);
    free(printbox);
    moveto(tempx,tempy);
}
/************************* length of file  *************************/
unsigned long filelength(signed int fid){
    struct stat buf;

    fstat(fid,&buf);
    return(buf.st_size);
}

/************************* graphics setup  *************************/
void open_graphics(char firstgraphics, char sei){
	char *display_name = NULL;
	unsigned long		changed_values;
	Window			parent;
	XSetWindowAttributes	setWindowAttr;
	XWindowAttributes	windowAttr;
	XGCValues               gcValues;


      /*there are many buit-in displat choises, including
      3200x1800 (16:9) Dell
      1600x1024 (3:2)
      1336x768  (16:9) ThinkPad
      1024x768  (4:3)
      600x800   (4:3)*/
	
    
	
    /*superVGA=1024  VGA=640*/
    /*        =768      =480*/
    /*
    if (XDisplayWidth(D,S)>=1152 && XDisplayHeight(D,S)>=900){
	  Maxx =1023;
	  WinMaxy =767;
    }
    */
    /*for smaller screen*/
    /*
    else{
	  Maxx = XDisplayWidth(D,S)-100;
	  WinMaxy = Maxx*480/640;
    }*/
    

    if (bground==0) bground='w';  /*background color default white*/
    

    if ((D = XOpenDisplay(display_name)) == NULL){
	fprintf(stderr, "%s: cannot connect to X server %s\n",
				"DDLab", XDisplayName(display_name));
	exit(-1);
    }
    S = DefaultScreen (D);


    
    
    //Maxx = (int)(XDisplayWidth(D,S) * .66);
    /*to give the same res as before on ThinkPad 925x694 where screen=1366x768*/
    Maxx = (int)(XDisplayWidth(D,S) * 924.0/1366);
    WinMaxy = (int) ceil(Maxx* (480.0/640));
    fprintf(stderr,"\nDisplay=%dx%d ",XDisplayWidth(D,S),XDisplayHeight(D,S));
    fprintf(stderr,"DDLabScreen=%dx%d",Maxx+1,WinMaxy+1);
    
    //WinMaxy = (int)(XDisplayHeight(D,S) * .9);
    //Maxx=1600;
    //WinMaxy=1024;
    //Maxx=924;  /*start size=925x768*/
    //WinMaxy=693;
    

    //Maxx=1023;  	     /*superVGA 1024  639*/
    //WinMaxy=767;        /*768  479*/
    //Maxx = XDisplayWidth(D,S)-100;
    //	  WinMaxy = Maxx*480/640;
    //	  Maxx=924;  /*start size=925x768*/
    //WinMaxy=693;
   
    Maxy=WinMaxy-vgay(16);/*window less bottom title bar*/



    //if (XDisplayWidth(D,S)-100 < Maxx)
    //       Maxx = XDisplayWidth(D,S) - 100;
    //WinMaxy = Maxx * 480/640;
    //Maxy = WinMaxy - vgay(16);

    startMaxx=Maxx;
    startWinMaxy=WinMaxy;

    /*Prepare window variables*/
    parent =  DefaultRootWindow (D);

    /*Create a simple window*/
    if (bground=='w'){ /*white background*/
       W = XCreateSimpleWindow (D, parent,
	      0, 0,		 /*x, y*/
	      Maxx+1, WinMaxy+1, /*height, width*/
	      1,		 /*border width*/
	      BlackPixel(D, S),  /*border color*/
	      WhitePixel(D, S)); /*window background color*/
    }
    else if (bground=='b'){  /*black background*/
       W = XCreateSimpleWindow (D, parent,
	      0, 0,				/*x, y*/
	      Maxx+1, WinMaxy+1, /*height, width*/
	      1,		 /*border width*/
	      WhitePixel(D, S),  /*border color*/
	      BlackPixel(D, S)); /*window background color*/
    }
    /*does this server support window backing stores?*/
    /* for BackingStore to work ...open an editor
    open the file XF86Config-4
    save it as... XF86Config-4.bak (just in case)
    scroll down to... Section "Device" (not Section "InputDevice")
    you will see various things listed,
    add... Option "BackingStore"*/
    if (DoesBackingStore(ScreenOfDisplay(D, S))){
	fprintf(stderr,"\nUsing backing store");
	changed_values = CWBackingStore;
	/*Now change the window attributes*/
	setWindowAttr.backing_store = WhenMapped;
	XChangeWindowAttributes(D, W, changed_values, &setWindowAttr);
    }

    /*get the screen depth (used by get image)*/
    XGetWindowAttributes(D, W, &windowAttr);
    screen_depth = windowAttr.depth;

    XSelectInput(D, W, ExposureMask|KeyPressMask|ButtonPressMask
	     |ButtonReleaseMask|PointerMotionMask|StructureNotifyMask);
    /*indicate if unregistered, or registered to soandso*/
    if (sei==1) XStoreName(D, W, "Discrete Dynamics Lab");
    else  XStoreName(D, W, "Discrete Dynamics Lab - UNREGISTERED");
    XMapRaised(D, W);

    gcValues.graphics_exposures = 0;

    Gc = XCreateGC (D, W, GCGraphicsExposures, &gcValues);

    XSetForeground(D, Gc, BlackPixel(D, S));
    XSetBackground(D, Gc, WhitePixel(D, S));
    XSetLineAttributes(D, Gc, 0, LineSolid, CapButt, JoinMiter);

    /*Wait for the first expose event.
      Then we know that the window is visible*/
    do {
	XNextEvent(D, &Event);
    } while (Event.type != Expose);

    leftCursor =XCreateFontCursor(D,XC_left_ptr);
    rightCursor =XCreateFontCursor(D,XC_right_ptr);
    XDefineCursor(D,W,rightCursor);
    mouse_found=1;

    setup_fonts(0);
    setup_colors();
    setup_images();

    *current_draw = W;
}

/***************** setup_images ************************/
void setup_images(void){
   int i;
        boximage =
		(Pixmap **)malloc(kNumBoxImages*sizeof(Pixmap*));
	for (i=0; i < kNumBoxImages; i++) {
	   boximage[i] =
		(Pixmap *)malloc(sizeof(Pixmap));
	   *boximage[i] = 0;
	}

        boximage_prompt =
		(Pixmap **)malloc(kNumBoxPromptImages*sizeof(Pixmap*));
	for (i=0; i < kNumBoxPromptImages; i++) {
	   boximage_prompt[i] =
		 (Pixmap *)malloc(sizeof(Pixmap));
	   *boximage_prompt[i] = 0;
	}
     
	stpimage = (Pixmap *)malloc(sizeof(Pixmap));
	*stpimage = 0;

	statblock = (Pixmap *)malloc(sizeof(Pixmap));
	*statblock = 0;

	current_draw = (Drawable *)malloc(sizeof(Drawable));
	*current_draw = 0;
}

/**************** free_images *************/
void free_images(void){
   int i;
	for (i=0; i < kNumBoxImages; i++) {
		if (*boximage[i] != 0)
			freeimage(boximage[i]);
	}
        free(boximage);
 
	for (i=0; i < kNumBoxPromptImages; i++){
	   if (*boximage_prompt[i] != 0)
		freeimage(boximage_prompt[i]);
	}    
        free(boximage_prompt);

	if (*stpimage != 0) freeimage(stpimage);
	if (*statblock != 0) freeimage(statblock);
   
}

/******** close the graphics, and free up stuff ******/
void close_graphics(void){

        free_fonts();
	free_images();
	XFreeCursor(D, leftCursor);
	XFreeCursor(D, rightCursor);
	XDestroyWindow(D,W);
	XFreeGC(D,Gc);
	XCloseDisplay(D);
}

/******** reset Maxx and Maxy after the window has been resized ******/
/*Simon 1/1/96*/
char resize_window(void){
   XWindowAttributes  windowAttr;
   signed int oldMaxx,oldWinMaxy,tempx,tempy;

	oldMaxx=Maxx;
	oldWinMaxy=WinMaxy;
	tempx=getx;
	tempy=gety;

	if (XGetWindowAttributes(D, W, &windowAttr) == 0){
	   fprintf(stderr, "%s: Failed to get window attributes.\n",
			"DDLab");
	   exit(-1);
	}
        /*if size not changed*/
        if (Maxx==windowAttr.width-1 && WinMaxy== windowAttr.height-1)
	                                        return(0);
        else{
	   Maxx = windowAttr.width-1;
	   WinMaxy = windowAttr.height-1;
	   Maxy = WinMaxy - vgay(16);
           Max_oy=Maxy*2; /*limit of oy, any oy greater is stuck (off screen) 
                         attractor are drawn, but not transients in draw_fan()*/
           /*only if x-screen is smaller, shrink fonts automatically,
           (there's a minimum size)
           if bigger, don't expand - this can be by hand*/
           //fprintf(stderr,"\nnew=%d .. old=%d",Maxx,oldMaxx); 
           if (Maxx<oldMaxx){
	     //fprintf(stderr,"\n>>new=%d .. old=%d",Maxx,oldMaxx); 
              free_fonts();
	      setup_fonts(0);
	      moveto(tempx*(float)Maxx/oldMaxx,tempy*(float)oldWinMaxy/WinMaxy);
              return(1);
           }
           else return(0);
        }
}

/***************** revise font size ************************/
void setup_fonts(signed int p_size){
      /*this gave seg fault with suse linux 
        because correct fonts were missing
      the folowing should be in /etc/X11/XF86Config 
      FontPath      "/usr/X11R6/lib/X11/fonts/misc"
      FontPath      "/usr/X11R6/lib/X11/fonts/75dpi"
      FontPath     "/usr/X11R6/lib/X11/fonts/100dpi"
      see also void set_small_font(void) in misc*.c */
  
  char using_backup_fonts=0;

    if (p_size<=0){
      signed int thisMaxx;
      /*if (Maxx>925) thisMaxx=925;
       else */
       thisMaxx=Maxx; 
       pointsize=ceil(11.5 * (float)(thisMaxx+1)/1024); //was 12.0
#if __DARWIN__
       pointsize*=1.3;
#endif
       if (pointsize%2==1){ /* even point only ??*/
	 if (XDisplayWidth(D,S)>1024) pointsize--;
	 else pointsize++;
       } 
       /*if (Maxx+1>=1024 && pointsize%2==1)
                pointsize--;*/  /* even point only ??*/
       /*else if (Maxx+1<=925 && pointsize%2==1)
	 pointsize--;*/  /* even point only ??*/
       if (pointsize <=8){ 
          pointsize=8;
          new_weight=1;
       }
       /*fprintf(stderr,"\n%d %f",pointsize,14.0 * (float)(thisMaxx+1)/1024);*/
    }
    else pointsize=p_size;
    
  
    if (new_weight==1) sprintf(textb[5],"medium");
    else if (new_weight==2) sprintf(textb[5],"bold");
    else sprintf(textb[5],"bold");
    /*load non-prop fonts*/
    sprintf(textb[0],"%s%s%s%d%s",
      "-adobe-courier-",textb[5],"-r-*-*-0-",pointsize*10,"-*-*-*-0-*-*");
    nonpropfont = XLoadQueryFont(D,textb[0]);
    if (nonpropfont==NULL){ 
         fprintf(stderr,
                  "\n can't load nonprop font %s, loading backup",textb[0]);
         sprintf(textb[0],"%s%s%s%d%s",
            "-*-*-",textb[5],"-r-*-*-*-",pointsize*10,"-*-*-*-*-*-*");
         nonpropfont = XLoadQueryFont(D,textb[0]);
    }
    sprintf(textb[0],"%s%d%s",
	     "-adobe-courier-medium-r-*-*-0-",pointsize*9,"-*-*-*-0-*-*");
    mediumnonpropfont = XLoadQueryFont(D,textb[0]);
    if (mediumnonpropfont==NULL){
         fprintf(stderr,
                 "\n can't load mediumnonpropfont %s, loading backup",textb[0]);
         sprintf(textb[0],"%s%d%s",
	     "-*-*-medium-r-*-*-*-",pointsize*9,"-*-*-*-*-*-*");
         mediumnonpropfont = XLoadQueryFont(D,textb[0]);
    }
    sprintf(textb[0],"%s%d%s",
	     "-adobe-courier-medium-r-*-*-0-",pointsize*6,"-*-*-*-0-*-*");
    smallnonpropfont = XLoadQueryFont(D,textb[0]);
    if (smallnonpropfont==NULL){
          fprintf(stderr,
                 "\n can't load smallnonpropfont %s, loading backup",textb[0]);
          sprintf(textb[0],"%s%d%s",
	     "-*-*-medium-r-*-*-*-",pointsize*6,"-*-*-*-*-*-*");
          smallnonpropfont = XLoadQueryFont(D,textb[0]);
    }
    if (nonpropfont!=NULL){
       XSetFont(D,Gc,nonpropfont->fid);
       if (CHeight_changed==0){
	  CHeight=(nonpropfont->ascent+nonpropfont->descent);
	  CWidth=nonpropfont->max_bounds.width;

#         if __LINUX__ /*UNIX text lines are further apart than LINUX*/
	  /*do nothing*/
#         elif __UNIX__
	     if (Maxx>925) CWidth*=.85;
	     /*if (Maxy>693) CHeight*=.85;*/ /*was too close at SFI*/
#         endif
       }
       /*fprintf(stderr,"CWidth=%d DHeight=%d\n",CWidth,CHeight);*/
    }
    else{
	  fprintf(stderr,"non-proportional font not found");
	  if (CHeight_changed==0){
	     CHeight=11;
	     CWidth=6;
	  }
    }

    /*load proportional font*/
    /*default size*/
    sprintf(textb[0],"%s%s%s%d%s",
	   "-*-times-",textb[5],"-r-*-*-*-",pointsize*10,"-*-*-*-*-*-*");
    propfont=XLoadQueryFont(D,textb[0]);
    if (propfont==NULL){ 
           fprintf(stderr,
                 "\n can't load propfont %s, loading backup",textb[0]);
           sprintf(textb[0],"%s%s%s%d%s",
	      "-*-*-",textb[5],"-r-*-*-*-",pointsize*10,"-*-*-*-*-*-*");
           propfont=XLoadQueryFont(D,textb[0]);
           using_backup_fonts=1;
    }
    /*medium*/
    sprintf(textb[0],"%s%d%s",
	   "-*-times-medium-r-*-*-*-",pointsize*9,"-*-*-*-*-*-*");
    mediumpropfont=XLoadQueryFont(D,textb[0]);
    if (mediumpropfont==NULL){
            fprintf(stderr,
                 "\n can't load mediumpropfont %s, loading backup",textb[0]);
           sprintf(textb[0],"%s%d%s",
	      "-*-*-medium-r-*-*-*-",pointsize*9,"-*-*-*-*-*-*");
           mediumpropfont=XLoadQueryFont(D,textb[0]);
           using_backup_fonts=1;
    }
    /*small*/
    sprintf(textb[0],"%s%d%s",
	   "-*-times-medium-r-*-*-*-",pointsize*6,"-*-*-*-*-*-*");    
    smallpropfont=XLoadQueryFont(D,textb[0]);
    if (smallpropfont==NULL){ 
            fprintf(stderr,
                 "\n can't load smallpropfont %s, loading backup",textb[0]);
            sprintf(textb[0],"%s%d%s",
	       "-*-*-medium-r-*-*-*-",pointsize*6,"-*-*-*-*-*-*");
            smallpropfont=XLoadQueryFont(D,textb[0]);
            using_backup_fonts=1;
    }
    /*load temporary font for dec/hex number in attractor basins*/
    sprintf(textb[0],"%s%d%s",
	   "-*-times-medium-r-*-*-*-",pointsize*8,"-*-*-*-*-*-*");
    tempfont=XLoadQueryFont(D,textb[0]);
    if (tempfont==NULL){ 
             fprintf(stderr,
                 "\n can't load tempfont %s, loading backup",textb[0]);
             sprintf(textb[0],"%s%d%s",
	        "-*-*-*-r-*-*-*-",pointsize*8,"-*-*-*-*-*-*");
             tempfont=XLoadQueryFont(D,textb[0]);
             using_backup_fonts=1;
    }

    /*-------------------------------------------------------------------*/
    /*sprintf(textb[0],"%s%d%s",
	   "-*-helvetica-medium-r-*-*-*-",pointsize*8,"-*-*-*-*-*-*");
	   tempfont=XLoadQueryFont(D,textb[0]);*/
    
    if (propfont!=NULL){
       XSetFont(D,Gc,propfont->fid);
       fonttype=1;
    }
    else fprintf(stderr,"selected proportional font not found");

    /*load italic proportional font*/
    sprintf(textb[0],"%s%s%s%d%s",
	   "-*-times-",textb[5],"-i-*-*-*-",pointsize*10,"-*-*-*-*-*-*");
    italicfont=XLoadQueryFont(D,textb[0]);
    if (italicfont==NULL){ 
            fprintf(stderr,
                 "\n can't load italicfont %s, loading backup",textb[0]);
           sprintf(textb[0],"%s%s%s%d%s",
	      "-*-*-",textb[5],"-i-*-*-*-",pointsize*10,"-*-*-*-*-*-*");
           italicfont=XLoadQueryFont(D,textb[0]);
    }
    if (using_backup_fonts==1) CHeight*=1.4;
    CHeight_def=CHeight;
    CWidth_def=CWidth;
    font_d_m_s='d'; /*keep track of font: d=default, m=medium, s=small*/
    //fprintf(stderr,"\nGSET: pointsize=%d",pointsize);
}

/******** free the fonts, Aug 2000  ******/
void free_fonts(void){
        /*free non-prop fonts*/
        if (nonpropfont != NULL){
	        //XUnloadFont(D, nonpropfont->fid);
	        XFreeFont(D,nonpropfont);
        }
        if (mediumnonpropfont != NULL){
	  //XUnloadFont(D, mediumnonpropfont->fid);
                XFreeFont(D,mediumnonpropfont);
        }
        if (smallnonpropfont != NULL){
	  //XUnloadFont(D, smallnonpropfont->fid);
                XFreeFont(D,smallnonpropfont);
        }        
        /*free non-prop fonts*/
	if (propfont != NULL){
	  //XUnloadFont(D, propfont->fid);
                XFreeFont(D,propfont);
        }
        if (mediumpropfont != NULL){
	  //XUnloadFont(D, mediumpropfont->fid);
                XFreeFont(D,mediumpropfont);
        }
	if (smallpropfont != NULL){
	  //XUnloadFont(D, smallpropfont->fid);
                 XFreeFont(D,smallpropfont);
        }
        /*free temp font*/
        if (tempfont != NULL){
	  //XUnloadFont(D, tempfont->fid);
                XFreeFont(D,tempfont);
        }
        /*free italic font*/
	if (italicfont != NULL){
	  //XUnloadFont(D, italicfont->fid); 
                XFreeFont(D,italicfont);
        }      
}

/******** revise window size, text font/size ?, backgrund color ******/
void revise_graphics(void){
    signed int xbox,tempMaxx,newMaxx,tempWinMaxy,
		 newheight,minx,miny;

  start:
    xbox=draw_prompt_box(4);
    setcolor(white);
    sprintf(textb[0],
      "window size=%dx%d resize/restore-w/W",Maxx+1,WinMaxy+1);
    outtext(textb[0]);
    moveto(xbox,gety+CHeight);
    sprintf(textb[0],"character width=%d height=%d pointsize=%d revise/restore-s/S",
					CWidth,CHeight,pointsize);
    outtext(textb[0]);
    moveto(xbox,gety+CHeight);
    outtext("colors: toggle background-b showold-o showall-a");
    moveto(xbox,gety+CHeight);
    outtext("flashing cursor speed-f, quit-q cont-ret:");
    input_string(1,0);
    erase_prompt_box(4);
    if (is[0]=='q' || is[0]==13) return;
    
    if (is[0]=='S'){
       free_fonts();
       new_weight=2;
       CHeight_changed=0;
       setup_fonts(0);
       //fprintf(stderr,"\nCWidth=%d CHeight=%d",CWidth,CHeight);
       goto start;
    }
    else if (is[0]=='s'){
      signed int newpointsize;
       xbox=draw_prompt_box(2);
       sprintf(textb[0],
         "set new font size (min 7 max 35, now %d):",pointsize);
       outtext(textb[0]);
       input_string(2,0);
       if (atoi(is)>=7) newpointsize=atoi(is);
       else newpointsize=pointsize;/*to prevent hard freeze in ubuntu*/

       sprintf(textb[0]," weight, bold-2 medium-1:");
       outtext(textb[0]);
       input_string(1,0);
       if (atoi(is)==1 || atoi(is)==2) new_weight=atoi(is);
       if (newpointsize>0 || new_weight==1 || new_weight==2){	 
	  free_fonts();
          setup_fonts(newpointsize);
       }
       moveto(xbox,gety+CHeight);
       sprintf(textb[0],"set new linespace (now %d):", CHeight);
       outtext(textb[0]);
       input_string(2,0);
       if (is[0]==13); /*do nothing*/
       else if (atoi(is)>1){
	  CHeight=atoi(is);
	  CHeight_changed=1;
       }
       goto start;
    }
    else if (is[0]=='f'){
       draw_prompt_box(1);
       sprintf(textb[0],
	  "change flashing cursor speed (%.1f): restore-r (1.0) or enter factor:",
	       (float)kCursorFlash/defCursorFlash);
       outtext(textb[0]);
       input_string(4,0);
       if (is[0]=='r'){
	  kCursorFlash=defCursorFlash;
          CursorFlash_auto_reset=0;
       }
       else if (is[0]==13); /*do nothing*/
       else if (isdigit(is[0]) || is[0]=='.'){ 
          kCursorFlash=
		 (unsigned long)((float)kCursorFlash/atof(is));
          CursorFlash_auto_reset=1;
       }
       goto start;
    }
    else if (is[0]=='b'){
       if (bground=='w'){ 
          bground='b';
          XSetWindowBackground(D,W,BlackPixel(D, S));
          XSetWindowBorder(D,W, WhitePixel(D, S));
       }
       else if (bground=='b'){ 
          bground='w';
          XSetWindowBackground(D,W, WhitePixel(D, S));
          XSetWindowBorder(D,W, BlackPixel(D, S));
       }
       setup_colors();
       show_old_colors();
       goto start;    
    }
    else if (is[0]=='o'){
       show_old_colors();
       goto start;
    }
    else if (is[0]=='a'){
       show_all_colors();
       goto start;
    }
    else if (is[0]=='w' || is[0]=='W'){
      int Monitor_maxx,Monitor_maxy;
      
       minx=300;
       miny=250;
       //fprintf(stderr,"\nmonitor=%dx%d pixels",XDisplayWidth(D,S),XDisplayHeight(D,S));
       Monitor_maxx=XDisplayWidth(D,S);
       Monitor_maxy=XDisplayHeight(D,S);
       tempMaxx=Maxx;
       tempWinMaxy=WinMaxy;

       if (is[0]=='w'){
	  xbox=draw_prompt_box(3);
	  setcolor(white);
	  sprintf(textb[0],"new window size (start=%dx%d, min=%dx%d, max=%dx%d)",
	       startMaxx+1,startWinMaxy+1,minx,miny,Monitor_maxx,Monitor_maxy);
	  outtext(textb[0]);
	  moveto(xbox,gety+CHeight);
	  sprintf(textb[0],"width (def %d):",Maxx+1);
	  outtext(textb[0]);
	  input_string(4,0);
	  if (is[0]!=13 && atoi(is)>=minx) newMaxx=atoi(is)-1;
	  else newMaxx=Maxx;
	  if (newMaxx>Monitor_maxx) newMaxx=Monitor_maxx-1;/*DDLab screen width < monitor width*/
	  Maxx=newMaxx;
	  moveto(xbox,gety+CHeight);       

          newheight=ceil((double)(newMaxx+1)*480.0/640);
          if (newheight<miny) newheight=miny;
          else if (newheight>Monitor_maxy) newheight=Monitor_maxy;
          sprintf(textb[0],"height (def %d):",newheight);
          outtext(textb[0]);
          input_string(4,0);
          WinMaxy=newheight;      
          if (is[0]!=13 && atoi(is)>=miny) WinMaxy=atoi(is)-1;       
          if (WinMaxy>Monitor_maxy) WinMaxy=Monitor_maxy-1;/*DDLab screen height < monitor width*/
          Maxy=WinMaxy-vgay(16);/*window less bottom title bar*/
          Max_oy=Maxy*2; /*limit of oy, any oy greater is stuck (off screen) 
                         attractor are drawn, but not transients in draw_fan()*/
      }
      else if (is[0]=='W'){ /*restore start*/
	 Maxx=startMaxx+1;
         WinMaxy=startWinMaxy;
         Maxy=WinMaxy-vgay(16);/*window less bottom title bar*/
         Max_oy=Maxy*2; /*limit of oy, any oy greater is stuck (off screen) 
                         attractor are drawn, but not transients in draw_fan()*/
      }
      if (tempMaxx!=Maxx || tempWinMaxy!=WinMaxy){
          XResizeWindow(D,W,Maxx+1,WinMaxy+1);
          if (Maxx<tempMaxx){              
             free_fonts();
	     setup_fonts(0);
	  }
          XSetFunction(D,Gc,GXcopy);	
	  draw_bottom_title(0); /*was (1)*/
          //draw_bottom_title(1);
          show_old_colors();
          goto start;
       }
       
    }
}
/************************* setup_colors ********************************/
void setup_colors(void){
  unsigned char i;   
  signed int  Number_of_colors;
  static char * color_name[]= {
        "White","Black","Yellow", "Gold", "Khaki", "Wheat", 
        "Tan", "Goldenrod", "Orange","Coral","Salmon", 
        "Red", "Orange Red", "Indian Red", "Firebrick", 
        "Brown","Sienna", "Maroon", "Medium Violet Red", 
        "Violet Red","Pink", "Green", "Spring Green", 
        "Medium Spring Green", "Green Yellow",
        "Pale Green","Yellow Green", "Lime Green", 
        "Medium Sea Green","Sea Green", "Forest Green",
        "Olive Drab", "Dark Olive Green", "Dark Green", 
        "Cadet Blue","Medium Aquamarine","Dark Turquoise", 
        "Turquoise", "Aquamarine", "Cyan","Blue", 
	"Medium Blue", "Medium Slate Blue",
        "Cornflower Blue","Sky Blue", "Light Blue", 
        "Light Steel Blue", "Steel Blue","Dark Slate Blue",
        "Navy", "Navy Blue", "Midnight Blue",
        /******** extra **********/
        "GhostWhite"
   };     
    
    nowcolor=             0; /*keeptrack of current forground color*/
    White=                0;
    Black=                1;
    Yellow=               2;
    Gold=                 3; 
    Khaki=                4;
    Wheat=                5;
    Tan=                  6;
    Goldenred=            7;
    Orange=               8;
    Coral=                9;
    Salmon=               10;
    Red=                  11;
    Orange_Red=           12;
    Indian_Red=           13;
    Firebrick=            14;
    Brown=                15;
    Sienna=               16;
    Maroon=               17;
    Medium_Violet_Red=    18;
    Violet_Red=           19;
    Pink=                 20;
    Green=                21;
    Spring_Green=         22;
    Medium_Spring_Green=  23;
    Green_Yellow=         24;
    Pale_Green=           25;
    Yellow_Green=         26;
    Lime_Green=           27;
    Medium_Sea_Green=     28;
    Sea_Green=            29;
    Forest_Green=         30;
    Olive_Drab=           31;
    Dark_Olive_Green=     32;
    Dark_Green=           33;
    Cadet_Blue=           34;
    Medium_Aquamarine=    35;
    Dark_Turquoise=       36;
    Turquoise=            37;
    Aquamarine=           38;
    Cyan=                 39;
    Blue=                 40;
    Medium_Blue=          41;
    Medium_Slate_Blue=    42;
    Cornflower_Blue=      43;
    Sky_Blue=             44;
    Light_Blue=           45;
    Light_Steel_Blue=     46; 
    Steel_Blue=           47;
    Dark_Slate_Blue=      48;
    Navy=                 49;
    Navy_Blue=            50;
    Midnight_Blue=        51;
    /******** extra *****/
    Ghost_White=           52;
    
    /*old color names*/
    if (bground=='w'){ /*default white background*/                
                black=       oldcolor[0]=White;
		blue=        oldcolor[1]=Gold;                 
		green=       oldcolor[2]=Medium_Sea_Green;   
		lightcyan=   oldcolor[3]=Brown;            
		lightred=    oldcolor[4]=Red;               
		magenta=     oldcolor[5]=Violet_Red;      
		brown=       oldcolor[6]=Dark_Green;      
		lightgray=   oldcolor[7]=Dark_Turquoise;
		darkgray=    oldcolor[8]=Ghost_White;
#                  if __UNIX__ /*if __LINUX__ stopped wrking*/
                      darkgray=    oldcolor[8]=Pale_Green;
#                  endif		
		lightblue=   oldcolor[9]=Cornflower_Blue;
		lightgreen=  oldcolor[10]=Lime_Green;    
		cyan=        oldcolor[11]=Olive_Drab;           
		red=         oldcolor[12]=Indian_Red;     
		//lightmagenta=oldcolor[13]=Violet_Red; this repeats magenta
                lightmagenta=oldcolor[13]=Orange;
		yellow=      oldcolor[14]=Blue;
		white=       oldcolor[15]=Black;
    } 
    else if (bground=='b'){ /*alternative black background*/
    
		black=       oldcolor[15]=Black;
		blue=        oldcolor[14]=Blue;
		green=       oldcolor[10]=Green;       
		lightcyan=   oldcolor[3]= Cyan;          
		lightred=    oldcolor[4]= Orange_Red;               
		magenta=     oldcolor[5]=Violet_Red;      
		brown=       oldcolor[6]=Sienna;   
		lightgray=   oldcolor[7]=Light_Steel_Blue;
		darkgray=    oldcolor[8]=Dark_Green;
		lightblue=   oldcolor[9]=Cornflower_Blue;
		lightgreen=  oldcolor[2]=Green_Yellow;
		cyan=        oldcolor[11]=Dark_Turquoise;           
		red=         oldcolor[12]=Salmon;     
		lightmagenta=oldcolor[13]=Pink; 
		yellow=      oldcolor[1]=Yellow;     
                white=       oldcolor[0]=White;
    }
    
    Number_of_colors=53;
    Color_Table=(int*)calloc( Number_of_colors,sizeof(int));
    
    default_cmap = DefaultColormap(D,S);
    for (i=0;i<Number_of_colors;i++){
        if(!XParseColor(D,default_cmap,color_name[i],&color_def))
                                      printf("\n color absent\n");
        XAllocColor(D,default_cmap,&color_def);
        Color_Table[i]=(int)color_def.pixel;
    }
}    

/********************* show all colors ******************************/
void show_all_colors(void){    
   signed int z,thisx,thisy,starty,Number_of_colors;   
   unsigned char c;
   unsigned long pixc;
   unsigned char rgb_red,rgb_green,rgb_blue;

    static char * color_name[]= {
        "White","Black","Yellow", "Gold", "Khaki", "Wheat", 
        "Tan", "Goldenrod", "Orange","Coral","Salmon", 
        "Red", "Orange Red", "Indian Red", "Firebrick", 
        "Brown","Sienna", "Maroon", "Medium Violet Red", 
        "Violet Red","Pink", "Green", "Spring Green", 
        "Medium Spring Green", "Green Yellow",
        "Pale Green","Yellow Green", "Lime Green", 
        "Medium Sea Green","Sea Green", "Forest Green",
	"Olive Drab", "Dark Olive Green", "Dark Green",
        "Cadet Blue","Medium Aquamarine","Dark Turquoise", 
        "Turquoise", "Aquamarine", "Cyan","Blue", 
        "Medium Blue", "Medium Slate Blue", 
        "Cornflower Blue","Sky Blue", "Light Blue", 
	"Light Steel Blue", "Steel Blue","Dark Slate Blue",
        "Navy", "Navy Blue", "Midnight Blue",
         /******** extra **********/
        "GhostWhite"
    };
    
    Number_of_colors=53;
    XClearWindow(D,W);

    moveto(vgax(5),vgay(50));
    thisx=getx;
    thisy=starty=gety;
    setcolor(white);
    set_medium_font();
    for(c=0;c< Number_of_colors;c++){
        setfillstyle(SOLID_FILL,c);
        bar( thisx,thisy,thisx+vgax(30),thisy+vgay(15));
        rectangle(thisx,thisy,thisx+vgax(30),thisy+vgay(15));
        for (z=0;z<=15;z++){
           if (c==oldcolor[z])
             rectangle(thisx-vgax(2),thisy-vgay(2),
                          thisx+vgax(30+2),thisy+vgay(15+2));
	}
        pixc=getpixel(thisx+1,thisy+1);

        rgb_red=((pixc>>16)&0xff);
        rgb_green=((pixc>>8)&0xff);
        rgb_blue=(pixc&0xff);

        sprintf(textb[1],"(%d,%d,%d)",rgb_red,rgb_green,rgb_blue);        
        /*sprintf(textb[0],"%d, %d, %lu, %s",
	  c,Color_Table[c],pixc,color_name[c]);*/
        sprintf(textb[0],"%d, %d, %s, %s",
	  c,Color_Table[c],textb[1],color_name[c]);
        moveto(thisx+vgax(35),thisy+vgay(10));
        outtext(textb[0]);
        moveto(getx-vgax(35),gety-vgay(10));
        
        if (Maxy-gety<70){
	     thisx+=vgax(200);
             thisy=starty;
        }
        else thisy+=vgay(20);
    }
    restore_def_font();
    setfillstyle(SOLID_FILL,black);
    draw_bottom_title(0); /*was (1)*/
}    

/***************** show old colors only ************************/
void show_old_colors(void){    
   signed int thisx,thisy,starty;    
   unsigned char c;
   unsigned long pixc;
   unsigned char rgb_red,rgb_green,rgb_blue;
 
    static char * color_name[]= {
        "White","Black","Yellow", "Gold", "Khaki", "Wheat", 
        "Tan", "Goldenrod", "Orange","Coral","Salmon", 
        "Red", "Orange Red", "Indian Red", "Firebrick", 
        "Brown","Sienna", "Maroon", "Medium Violet Red", 
        "Violet Red","Pink", "Green", "Spring Green", 
        "Medium Spring Green", "Green Yellow",
        "Pale Green","Yellow Green", "Lime Green", 
        "Medium Sea Green","Sea Green", "Forest Green",
        "Olive Drab", "Dark Olive Green", "Dark Green", 
        "Cadet Blue","Medium Aquamarine","Dark Turquoise", 
        "Turquoise", "Aquamarine", "Cyan","Blue", 
        "Medium Blue", "Medium Slate Blue", 
        "Cornflower Blue","Sky Blue", "Light Blue", 
        "Light Steel Blue", "Steel Blue","Dark Slate Blue",
        "Navy", "Navy Blue", "Midnight Blue",
	 /******** extra **********/
	"GhostWhite"
    };
    /*old color name buf*/ 
    static char * old_color_name[]= {           
        "black","blue","green","lightcyan","lightred","magenta","brown",
        "lightgray","darkgray","lightblue","lightgreen",
        "cyan","red","lightmagenta","yellow","white" 
    };
      
    XClearWindow(D,W);      
    moveto(vgax(5),vgay(50));
    thisx=getx;
    thisy=starty=gety;
    setcolor(white);
    set_medium_font();
    for(c=0;c<=15;c++){
        setfillstyle(SOLID_FILL,oldcolor[c]);
        bar( thisx,thisy,thisx+vgax(30),thisy+vgay(15));
        rectangle(thisx,thisy,thisx+vgax(30),thisy+vgay(15));
        pixc=getpixel(thisx+1,thisy+1);
        pixc=getpixel(thisx+1,thisy+1);

        rgb_red=((pixc>>16)&0xff);
        rgb_green=((pixc>>8)&0xff);
        rgb_blue=(pixc&0xff);

        sprintf(textb[1],"(%d,%d,%d)",rgb_red,rgb_green,rgb_blue);
        sprintf(textb[2],"(%.3f,%.3f,%.3f)",
            (float)rgb_red/255,(float)rgb_green/255,(float)rgb_blue/255);

        sprintf(textb[0],"%d: new=%d defno=%d getpix=%lu, %s, %s, %s, %s",
            c,oldcolor[c],Color_Table[oldcolor[c]],pixc,
                textb[1],textb[2],old_color_name[c],color_name[oldcolor[c]]);
        moveto(thisx+vgax(35),thisy+vgay(10));
        outtext(textb[0]);
        moveto(getx-vgax(35),gety-vgay(10));
        
        if (Maxy-gety<70){
             thisx+=vgax(200);
             thisy=starty;
	}
        else thisy+=vgay(20);
    }
    restore_def_font();
    setfillstyle(SOLID_FILL,black);
    draw_bottom_title(0);/*was (1)*/
}    

/************************ revise text size ******************************/
/*
void revise_text_size(void){
 signed int xbox,newwidth,newheight;

  start:
       setcolor(white);
       setusercharsize(txd,tx2,tyd,ty2);
       xbox=draw_prompt_box(4);
       sprintf(textb[0],"this is default textsize width-%d x height-%d,",
				      textwidth("z"),textheight("z"));
       outtext(textb[0]);
       moveto(xbox,gety()+textscale);
       outtext("to alter, enter x factor:");
       input_string(3,1);
       if (is[0]!=13) tx1=(signed int)((float)txd*atof(is));
       if (is[0]=='q') goto end;
       outtext(" , enter y factor:");
       input_string(3,1);
       if (is[0]!=13) ty1=(signed int)((float)tyd*atof(is));
       if (is[0]=='q') goto end;
       setusercharsize(tx1,tx2,ty1,ty2);
       newwidth=teLxtwidth("z");
       newheight=textheight("z");
       setusercharsize(txd,tx2,tyd,ty2);
       moveto(xbox,gety()+textscale);
       sprintf(textb[0],"new textsize is %d x %d,",newwidth,newheight);
       outtext(textb[0]);
       moveto(xbox,gety()+textscale);
       outtext(" revise-r, q-to abandon change, return to accept:");
       input_string(1,0);
       if (is[0]=='r') goto start;
       if (is[0]==13) setusercharsize(tx1,tx2,ty1,ty2);
  end:
       cleardevice();
}
*/
# endif
/*------------------------ end UNIX graphics --------------------*/

/*------------------------ WATCOM graphics ----------------------*/
# if __WATCOM__

/*for memory available, watcom only*/
#include <i86.h>

/***************  list of functions in this file *************/

/*void putimage(int x, int y, char *image,
               int drawing_mode, char *which_image)*/
/*signed int getmaxx(void)*/
/*signed int getmaxy(void)*/
/*signed int textheight(char *buf)*/
/*signed int textwidth(char *buf)*/
/*signed int text_pix_width(char *textbuf)*/
/*void outtext(char *buf)*/
/*void line(signed int xpos,signed int ypos,
	  signed int xpos1,signed int ypos1)*/
/*void putpixel(signed int xpos, signed int ypos, signed int color)*/
/*void setfillstyle(signed int pattern, signed int color)*/
/*void bar3d(signed int left, signed int top,
	   signed int right, signed int bottom,
		   signed int depth, signed int topflag)*/
/*void fillpoly(signed int numpoints, signed int polypoints[])*/
/*void pieslice(char pi_outline,signed int x,signed int y,
	    signed int s_angle,signed int e_angle,signed int radius)*/
/*void setviewport(signed int left,signed int top,
    signed int right, signed int bottom,
                  signed int clip);*/
/*void open_graphics(char firstgraphics, char sei)*/
void draw_intro_text(char firstgraphics);
void revise_text_size(void);
void setup_VGA_colors(void);
void setup_hires_colors(void);
static void bitImage(signed int N);
unsigned char getScrBits_Port( unsigned char notcolor1,
	  unsigned char notcolor2,signed int px, signed int py);
unsigned char getScrBits_Land( unsigned char notcolor1,
	   unsigned char notcolor2,signed int px, signed int py);
/*void printimage(char Land_Port,
    unsigned char notcolor1,unsigned char notcolor2,
      signed int x1,signed int y1,signed int x2, signed int y2)*/
/*void print_out(char *array)*/
void print_option(void);
void select_print_style(void);
/*void mouse_call(regax,regbx,regcx,regdx)*/
/*unsigned long get_memory(void)*/

signed int g_status;
char CHeight_changed=0;
/********** translate borland -> warcom functions  feb 94 *********/
void putimage(int x, int y, char *image,
	      int drawing_mode, char *which_image){
     _putimage(x,y,image,drawing_mode);
}
/****************** getmaxx() ********************/
signed int getmaxx(void){
       _getvideoconfig(&vc);
       return(vc.numxpixels-1);
}
/****************** gety ********************/
signed int getmaxy(void){
       _getvideoconfig(&vc);
       return(vc.numypixels-1);
}

/****************** textheight(char buf) ********************/
signed int textheight(char *buf){

  if (sfont<=0){
     struct xycoord concat;
     struct xycoord extent[4];
       _gettextextent(xy.xcoord,xy.ycoord,buf,&concat,&extent);
       return(extent[0].ycoord-extent[3].ycoord);
  }

  else{
  /*struct _fontinfo info;*/
       _getfontinfo(&info);
       return(info.pixheight);
  }
}

/****************** textwidth(char buf) ********************/
signed int textwidth(char *buf){

    if (sfont==0){
      signed int z;
      struct xycoord concat;
      struct xycoord extent[4];
      /*_gettextextent(xy.xcoord,xy.ycoord,buf,&concat,&extent);*/
      _gettextextent(0,0,buf,&concat,&extent);
       if (strlen(buf)==1)
	  return((signed int)((float)
		     ((extent[1].xcoord-extent[0].xcoord)*6)/7));
       else return(extent[1].xcoord-extent[0].xcoord);
    }
    else return(_getgtextextent(buf));
}
/****** get actual pix length of string, in case prop font char width varies ****/
signed int text_pix_width(char *textbuf){
  signed int textw,texth,thisx,thisy;
     thisx=getx;
     thisy=gety;
     moveto(0,-50);//above visible screen
     outtext(textbuf);
     textw=getx;  //text_pix_length
     moveto(thisx,thisy); //restore position
     return(textw);        
}
/****************** outtext(char buf) ********************/
void outtext(char *buf){

   /*use selected font*/
   /*if (getcolor()==black) setcolor(white);*/
   if (sfont>0) _outgtext(buf);
   /*text as line segments*/
   else{
     struct xycoord concat;
     struct xycoord extent[4];
       moverel(0,2);
       xy=_getcurrentposition();
       _gettextextent(xy.xcoord,xy.ycoord,buf,&concat,&extent);
       _grtext(xy.xcoord,xy.ycoord,buf);
       _moveto(concat.xcoord,concat.ycoord-2);
   }
}

/****************** line(x,y,x1,y1) ********************/
void line(signed int xpos,signed int ypos,
	     signed int xpos1,signed int ypos1){
  signed int tempx,tempy;

	tempx=getx;
	tempy=gety;

       _moveto(xpos,ypos);
       _lineto(xpos1,ypos1);
       _moveto(tempx,tempy);
}

/****************** getcolor() ********************/
void putpixel(signed int xpos, signed int ypos, signed int color){
  unsigned char(tempcolor);

     tempcolor=_getcolor();
     _setcolor(color);
     _setpixel(xpos,ypos);
     _setcolor(tempcolor);

}
/****************** fillstyle ********************/
void setfillstyle(signed int pattern, signed int color){
    char z;
    unsigned char new_mask[8];
    /*
    char new_mask[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
    */
    if (pattern==SOLID_FILL){
	 for (z=0;z<=7;z++) new_mask[z]=0xff;
    }

    else if (pattern==CLOSE_DOT_FILL){
	 new_mask[0]=new_mask[4]=0x88;
	 new_mask[1]=new_mask[3]=new_mask[5]=new_mask[7]=0x00;
	 new_mask[2]=new_mask[6]=0x22;
	 /*
	 for (z=0;z<=7;z+=2) new_mask[z]=0xaa; //checkerboard
	 for (z=1;z<=7;z+=2) new_mask[z]=0x00;
	 */
    }

    else if (pattern==INTERLEAVE_FILL){
	 for (z=0;z<=7;z+=2) new_mask[z]=0xcc;
	 for (z=1;z<=7;z+=2) new_mask[z]=0x33;
    }
    _setfillmask(new_mask);
    fillcolor=color;
}

/****************** bar ********************/
void bar(signed int left, signed int top,
		 signed int right, signed int bottom){
    unsigned char tempcolor;

	tempcolor=_getcolor();
	_setcolor(fillcolor);
	_rectangle(_GFILLINTERIOR,left,top,right,bottom);
	_setcolor(tempcolor);

}
/****************** bar3d ********************/
void bar3d(signed int left, signed int top,
		    signed int right, signed int bottom,
				  signed int depth, signed int topflag){
    unsigned char tempcolor;

	tempcolor=_getcolor();
	_setcolor(fillcolor);
	_rectangle(_GFILLINTERIOR,left,top,right,bottom);
	_setcolor(tempcolor);
	_rectangle(_GBORDER,left,top,right,bottom);
}
/****************** poly ********************/
void fillpoly(signed int numpoints, signed int polypoints[]){
     unsigned char tempcolor;
     struct xycoord points[6];
     signed int z;

       for (z=0;z<=numpoints-1;z++){
	   points[z].xcoord=polypoints[z*2];
	   points[z].ycoord=polypoints[z*2+1];
       }
       tempcolor=_getcolor();
       _setcolor(fillcolor);
       _polygon(_GFILLINTERIOR,numpoints,&points);
       _setcolor(tempcolor);
}

/********* draw a filled circle and diff color outline ***********/
void pieslice(char pi_outline,signed int x,signed int y,
	    signed int s_angle,signed int e_angle,signed int radius){
  unsigned char tempcolor;

   tempcolor=getcolor();
   setcolor(fillcolor);
   _ellipse(_GFILLINTERIOR,x-radius,y-radius,x+radius,y+radius);
   if (pi_outline==2 && radius>=2){ /*draw black outline if circle>=4 pixels, for 3d iso*/
      setcolor(tempcolor);
      _ellipse(_GBORDER,x-radius,y-radius,x+radius,y+radius);
   }
   if (pi_outline==1 && radius>=3){ /*draw contrasting outline if circle>=6 pixels*/
      setcolor(tempcolor);
      _ellipse(_GBORDER,x-radius,y-radius,x+radius,y+radius);
   }
   setcolor(tempcolor);
}
/*********** clip graphics in a rectangle **************/
void setviewport(signed int left,signed int top,
    signed int right, signed int bottom,
		 signed int clip){

   _setcliprgn(left,top,right,bottom);
   view_x0=left;
   view_y0=top;
   view_x1=right;
   view_y1=bottom;
}
/************** Watcom: set up graphics, VGA or Super VGA ********************/
void open_graphics(char firstgraphics, char sei){

char firsttry;
signed int
  z,zz,max,
  errorcode,
  gdriver,
  xbox,
  mode;


    if (hires==2) mode=_XRES16COLOR; /*1024 x 768*/
    else if (hires==1) mode=_SVRES16COLOR; /*800 x 600*/
    else {
       hires=0;
       mode=_VRES16COLOR;       /*640 x 480 */
    }
    _setvideomode(mode);
    _getvideoconfig(&vc);
    _gettextsettings(&ts);

    Maxx=vc.numxpixels-1;
    Maxy=vc.numypixels-1-(signed int)
			  (14*((float)vc.numypixels/480));

    /*default line segment font*/    txd=tx1=vgax(7);
    tyd=ty1=vgay(9);
    _setcharsize(ty1,tx1);
    
    /*sprintf(textb[0],"txd=%d, tyd=%d, tx1=%d, tx1=%d",
       txd, tyd, tx1, ty1);
    draw_prompt_box(1);
    outtext(textb[0]);
    input_string(1,0);*/

    if (hires==0) _setcharspacing(-2);
    else _setcharspacing(-3);
     _gettextsettings(&ts);
    if (CHeight_changed==0){
       pointsize=txd=tx1=CWidth=ts.width;
       tyd=ty1=CHeight=ts.height;
    }


    if (firstgraphics==0){  /*default background color is white*/
       if (bground==0) bground='w';
    }
    _settextorient(1,0);  //watcom

    /*names for colors*/
    //if (hires==0) setup_VGA_colors();
    //if (hires) setup_hires_colors();

    setup_VGA_colors();

    mouse_call(0,0,0,0); /*reset mouse*/
    mouse_found=abs(globax); /*-1 if found, 0 if not*/
    if (mouse_found){
       mouse_x=Maxx/2.5; /*initial position of mouse*/
       mouse_y=22;
       mouse_call(4,0,mouse_x,mouse_y); /*place mouse*/
       mouse_call(7,0,0,getmaxx());  /*allow whole screen*/
       mouse_call(8,0,0,getmaxy());
       mouse_call(1,0,0,0); /*display mouse*/
       button=button_not_rel=0;
    }
    /*_unregisterfonts();*/
    if (firstgraphics==0) sfont=0;
    if (hires==0){
	nfonts=_registerfonts("smallf.fon");
	g_status=_grstatus();
    }
    else{
       nfonts=_registerfonts("seriff.fon");
       g_status=_grstatus();
    }

    if (g_status==_GROK){  /*fonts loaded ok*/
       if (firstgraphics==0){
	  if (hires==0) sfont=2;
	  else if (hires==1) sfont=6;
	  else if (hires==2) sfont=5;
          font_d_m_s='d';/*default text size*/
       }
       sprintf(textb[0],"n%d",sfont);
       _setfont(textb[0]);
       _getfontinfo(&info);
       if (CHeight_changed==0){
	  CHeight=info.pixheight;
	  pointsize=CWidth=info.avgwidth;
       }
       
    }
    if (firstgraphics==0) return;
    else{
	revise:
	 draw_intro_text(firstgraphics);
	 xbox=draw_prompt_box(4);
	 if (hires==0){
	    sprintf(textb[0],
	      "screen=%dx%d change:1024x768-h 800x600-m",
		vc.numxpixels,vc.numypixels);
	 }
	 if (hires==1){
	    sprintf(textb[0],
	      "screen=%dx%d change:1024x768-h 640x480-l",
		 vc.numxpixels,vc.numypixels);
	 }
	 if (hires==2){
	    sprintf(textb[0],
	       "screen=%dx%d change:800x600-m 640x480-l",
		  vc.numxpixels,vc.numypixels);
	 }
	 outtext(textb[0]);
	 moveto(xbox,gety+CHeight);
	 outtext("colors: tog background-b");
	 moveto(xbox,gety+CHeight);
	 outtext("fontsize-s linespace-v");
          moveto(xbox,gety+CHeight);
	 outtext("flashing cursor speed-f, quit-q cont-ret:");
	 input_string(1,0);
	 if (is[0]=='q' || is[0]==13) return;
	 erase_prompt_box(4);
         if (is[0]=='f'){
            draw_prompt_box(1);
            outtext(
              "change flashing cursor speed: restore-r or enter factor:");
            input_string(4,0);
            if (is[0]=='r') kCursorFlash=defCursorFlash;
            else if (is[0]==13); /*do nothing*/
            else if (isdigit(is[0]) || is[0]=='.')
               kCursorFlash=
		 (unsigned long)((float)kCursorFlash/atof(is));
            goto revise;
         }

	 else if (is[0]=='s' && sfont<=0){ /*prop fonts not installed*/
	    revise_text_size();        /*use line segments*/
	    draw_intro_text(firstgraphics);
	    goto revise;
	 }

	 else if (is[0]=='s' && sfont>=1){ /*prop fonts installed*/
	    /*fonts*/
	    cleardevice();
	    setcolor(white);
	    moveto(30,20);

	    for (z=1;z<=nfonts;z++){
	       sprintf(textb[0],"n%d",z);
	       _setfont(textb[0]);
	       _getfontinfo(&info);
	       sprintf(textb[0],"%d-%s-%s, h=%d, w=%d, aw=%d 1234567890",
		  z,info.filename,info.facename,info.pixheight,
				      info.pixwidth,info.avgwidth);
	       _outgtext(textb[0]);
	       moveto(30,gety+info.pixheight);
	       /*getch();*/
	       if (gety>getmaxy()-50){
		  input_string(1,0);
		  cleardevice();
		  moveto(30,20);
	       }
	    }
	    moveto(30,gety+tyd);
	    _grtext(getx,gety,
               "line seg font 1234567890, to select enter 0");
	    if (hires==0) sfont=2;
	    else if (hires==1) sfont=6;
	    else if (hires==2) sfont=5;
	     sprintf(textb[0],"n%d",sfont);
	    _setfont(textb[0]);
	    _getfontinfo(&info);
	    CHeight=info.pixheight;
	    pointsize=CWidth=info.avgwidth;
	    moveto(30,gety+info.pixheight);
	    sprintf(textb[0],
	    "font %d, to change enter font no:",sfont);
	    _outgtext(textb[0]);
	    input_string(1,1);
	    if (is[0]==13);
	    else if (atoi(is)<=nfonts && atoi(is)>0){
		  sfont=atoi(is);
		  sprintf(textb[0],"n%d",sfont);
		  _setfont(textb[0]);
		  _getfontinfo(&info);
		  CHeight=info.pixheight;
		  pointsize=CWidth=info.avgwidth;
	    }
	    else if (atoi(is)==0) sfont=0;
            font_d_m_s='d';/*default text size*/
	    cleardevice();
	    goto revise;
	 }
	 else if (is[0]=='v'){
	    draw_prompt_box(1);
	    sprintf(textb[0],
	       "set new linespace (now %d):",CHeight);
	    outtext(textb[0]);
	    input_string(2,0);
	    if (atoi(is)>1){
	       CHeight=atoi(is);
	       CHeight_changed=1;
	    }
	    goto revise;
	 }
	 /*********************/
	 else if (is[0]=='b'){
	    if (bground=='w') bground='b';	       
	    else if (bground=='b') bground='w';
	    open_graphics(1,0); /* revise graphics setup */
	    goto revise;
	 }
	 erase_prompt_box(4);
	 if (hires==0) sfont=2;
	 else sfont=5;

	 if (is[0]=='h' || is[0]=='m' || is[0]=='l'){
	    if (is[0]=='h') hires=2;
	    else if (is[0]=='m') hires=1;
	    else if (is[0]=='l') hires=0;

	    if (hires==0) sfont=2;
	    else if (hires==1) sfont=6;
	    else if (hires==2) sfont=5;
	    CHeight_changed=0;
	    open_graphics(1,0); /* revise graphics setup */
	    goto revise;
	 }
    }
}

/********************** draw intro text etc ********************************/
void draw_intro_text(char firstgraphics){
signed int z,zz,leftx,max;

	cleardevice();
	setcolor(white);
	leftx=vgax(20);
	_setcharsize(ty1,tx1);
	_gettextsettings(&ts);

	if (firstgraphics==1){
		draw_bottom_title(1);
		moveto(leftx, vgay(10));
		sprintf(textb[0],"CHeight=%d",CHeight);
		   outtext(textb[0]);

		moveto(leftx,vgay(20));
		memory_box(1,NULL);

		moveto(leftx, gety+info.pixheight);
		outtext ("DISCRETE DYNAMICS LAB");
		moveto(leftx, gety+CHeight);

		if (nfonts>0){
		   sprintf(textb[0],"%d fonts loaded",nfonts);
		   outtext(textb[0]);
		}
		else{
		   outtext("font load failed,");
		   moveto(leftx, gety+CHeight);
		   sprintf(textb[0],"font load failed, g_status=%d",
					      g_status);
		   outtext(textb[0]);
		   moveto(leftx, gety+CHeight);
		   outtext("using the default line segment font");
		   outtext(textb[0]);
		   moveto(leftx, gety+CHeight);
		   outtext("the size of this font can be changed");

		}
		moveto(leftx, gety+CHeight);

		outtext("Graphics Setup");
		moveto(leftx, gety+CHeight*2.2);

		_getvideoconfig(&vc);
		sprintf(textb[4],
		 "graphics=%dx%d, colors=%d, Maxx=%d, Maxy=%d",
			  vc.numxpixels,vc.numypixels,vc.numcolors,
				     Maxx,Maxy);
		outtext(textb[4]);
		moveto(leftx, gety+textheight("s"));
	   //if (hires==0){
		//max=getmaxcolor();
		max=vc.numcolors;
		for (z=0;z<=max-1;z++){
			moveto(leftx, gety+CHeight);
			setcolor(z);
			moveto(leftx,gety);
			sprintf(textb[0],"%d",z);
			outtext(textb[0]);
			lineto(vgax(100),gety);

			setcolor(white);
			setfillstyle(SOLID_FILL, z);
			bar3d(getx, gety,getx+vgax(50), 
                              gety+CHeight-vgay(2),0,0);
			/*show color name*/
			moverel(vgax(60),0);
			if (black==z) sprintf(textb[0],"black");
			else if (blue==z) sprintf(textb[0],"blue");
			else if (green==z) sprintf(textb[0],"green");
			else if (cyan==z) sprintf(textb[0],"cyan");
			else if (red==z) sprintf(textb[0],"red");
			else if (magenta==z) sprintf(textb[0],"magenta");
			else if (brown==z) sprintf(textb[0],"brown");
			else if (lightgray==z) sprintf(textb[0],"lightgray");
			else if (darkgray==z) sprintf(textb[0],"darkgray");
			else if (lightblue==z) sprintf(textb[0],"lightblue");
			else if (lightgreen==z) sprintf(textb[0],"lightgreen");
			else if (lightcyan==z) sprintf(textb[0],"lightcyan");
			else if (lightred==z) sprintf(textb[0],"lightred");
			else if (lightmagenta==z) sprintf(textb[0],"lightmagenta");
			else if (yellow==z) sprintf(textb[0],"yellow");
			else if (white==z) sprintf(textb[0],"white");

			outtext(textb[0]);
			moverel(vgax(-60),0);
		}
	   //}
	   /*
	   if (hires==1){
		max=255;
		moveto(20, gety);
		for (z=0;z<=max;z++){

			setcolor(z);
			moveto(getx+textwidth("s")+15,gety);
			if (z%8==0) moveto(20,gety+textheight("s"));


			if (z<10) sprintf(textb[0],"  %d",z);
			if (z>9 && z<100) sprintf(textb[0]," %d",z);
			if (z>99) sprintf(textb[0],"%d",z);
			outtext(textb[0]);
			lineto(getx+10,gety);

			setcolor(white);
			setfillstyle(SOLID_FILL, z);
			bar3d(getx, gety, getx+20,
				gety+textheight("s")-2,0,0);
		}
	   }


	   moveto(20, gety+textheight("s")*2);
	   sprintf(textb[0],"this is style %d",font);
	   outtext(textb[0]);

	   textscale=textheight("z");

	   setcolor(white);

	   moveto(20, gety+textheight("s")*2);

	   _setcharsize(tyd,txd);
	   _gettextsettings(&ts);

	   outtext("to change enter textstyle 0-10 (this is 2),");
	   moveto(20, gety+textheight("s"));
	   outtext("Return-accept and see graghics options");
	   input_string(2,0);

	   if (is[0]=='q') return;

	   if (is[0]!=13){
		font=atoi(is);
		goto start;
	   }*/
	}
}


/************************ revise text size ******************************/
void revise_text_size(void){
   signed int xbox,newwidth,newheight;

	     start:
		  _setcharsize(tyd,txd);
		  _gettextsettings(&ts);

		  pointsize=CWidth=ts.width;
		  CHeight=ts.height;
		  xbox=draw_prompt_box(4);
		  sprintf(textb[0],
		     "default textsize width-%d x height-%d,",
				 CWidth,CHeight);
		  outtext(textb[0]);
		  moveto(xbox,gety+CHeight);
		  outtext("width (pixels):");

		  input_string(3,1);
		  if (is[0]!=13) tx1=atoi(is);

		  if (is[0]=='q') goto end;

		  outtext(" height (pixels):");

		  input_string(3,1);
		  if (is[0]!=13) ty1=atoi(is);
		  if (is[0]=='q') goto end;

		  /*default line segment font*/

		  _setcharsize(ty1,tx1);
		  _gettextsettings(&ts);

		  pointsize=CWidth=ts.width;
		  CHeight=ts.height;

		  moveto(xbox,gety+CHeight);
		  sprintf(textb[0],"new textsize = %d x %d,",
				 CWidth,CHeight);
		  outtext(textb[0]);

		  moveto(xbox,gety+CHeight);
		  outtext
		  ("revise-r accept-ret:");

		  input_string(1,0);
		  if (is[0]=='r') goto start;

		  _setcharsize(ty1,tx1);
		  _gettextsettings(&ts);

	     end:
		  cleardevice();
}

/*************************** set up colors ***************************/
void setup_VGA_colors(void){
signed int redc,greenc,bluec;

	if (bground=='w'){
			black=         0; /*white*/
			white=	      15; /*black*/
			blue=	      14;
			green=	       2; /*lightgreen*/
			cyan=	       6; /*brown*/
			red=	      12;
			magenta=       5;
			brown=	       8;
			lightgray=    11; /*lightgray*/
			darkgray=      7; /*darkgray*/
			lightblue=     9;
			lightgreen=   10; /*green*/
			lightcyan=     3; /*cyan*/
			lightred=      4; /*red*/
			lightmagenta= 13;
			yellow=	       1; /*blue*/

			/*reset palette 0 to white*/
			//setpalette(0,63);
			//setpalette(15,0);

			_remappalette(0,_BRIGHTWHITE);
			_remappalette(15,_BLACK);

			setcolor(white);

	}

	if (bground=='b'){

			black=	      0;
			blue=	      1;
			green=	     10; /**/
			cyan=	      3;
			red=	      4;
			magenta=      5;
			brown=	      6;
			lightgray=    7;
			darkgray=     8;
			lightblue=    9;
			lightgreen=   2;
			lightcyan=    11; /**/
			lightred=     12; /**/
			lightmagenta= 13;
			yellow=	      14; /**/
			white=	      15;

			/*setbkcolor(black);*/
			//setpalette(0,0);
			//setpalette(15,63);

			_remappalette(0,_BLACK);
			_remappalette(15,_BRIGHTWHITE);
	 }
}

/******************************************************/
/*
void setup_hires_colors(void){
	//define colors for IBM8514   color no, red, green, blue
signed int redc,greenc,bluec,z;

	   z=0;
	   for (redc=0;redc<=7;redc++){
	     for (greenc=0;greenc<=7;greenc++){
	       for (bluec=0;bluec<=3;bluec++){
		 z++;
		 setrgbpalette(z-1,
			redc*32+(redc*4+3),
			    greenc*32+(greenc*4+3),
				bluec*64+(bluec*8+7));
	       }
	     }
	   }




	  //colours for basins
	  //lightred
	  //lightcyan
	  //yellow
	  //green


	  if (bground=='w'){
		black=	        0; //white
		blue=	        3;
		green=	       12; //green*****
		cyan=	      136; //brown
		red=	      232; //224
		magenta=      230;
		brown=	      136;
		lightgray=     80;
		darkgray=     150; //186
		lightblue=     23; //brown  23
		lightgreen=     8; //dark green  8
		lightcyan=    100; //brown***********
		lightred=     224; //red*************
		lightmagenta= 238;
		yellow=         2; //blue************
		white=        255; //black

		setrgbpalette(0,255,255,255);//reset palette 0 to white
		setrgbpalette(255,0,0,0);

		setcolor(white);
	   }

	   if (bground=='b'){


		black=	        0;
		blue=	       15;
		green=	       80;
		cyan=	       19;
		red=	      224;
		magenta=      230;
		brown=	      136;
		lightgray=     22;
		darkgray=      37;
		lightblue=     23;
		lightgreen=    88;
		lightcyan=     27;
		lightred=     232;
		lightmagenta= 238;
		yellow=	      253;
		white=	      255;

		setrgbpalette(0,0,0,0);//reset palette 0 to black
		setrgbpalette(255,255,255,255);
		setcolor(white);
	   }
}
*/
/******************** PintImage Aug 93 ********************************/
static void bitImage(signed int N){
	/*set epson printer to bit image mode,
	N is the number of bytes to print*/

	signed int n1,n2;

	n2=N >> 8;
	n1=N-(n2 << 8);

	prn_putc(ESC);

	/*epson lq-570*/
	/*prn_putc('*');*/ /*K=standard density*/
	/*prn_putc(4); */  /*L=double density*/
			   /*Y=dbl speed + dbl density*/
			   /*Z=quad density*/
	/*epson mx-82*/
	prn_putc(75);      /*turns on normal density bit image mode*/

	prn_putc(n1);
	prn_putc(n2);
}

/****************************************************/
unsigned char getScrBits_Port( unsigned char notcolor1,
	  unsigned char notcolor2,signed int px, signed int py){

 char z;
 unsigned char firePins=0;

    py--;
    for(z=7;z>=0;z--){
       py++;
       if (getpixel(px,py)==0 || getpixel(px,py)==darkgray
	  || getpixel(px,py)==notcolor1
	    || getpixel(px,py)==notcolor2);/*do nout*/
       else firePins+=(char)pow(2,(float)z);
    }
    return firePins;
}

/* * * * * * * * * * * * * * * * * * * * * * * * */
unsigned char getScrBits_Land( unsigned char notcolor1,
	   unsigned char notcolor2,signed int px, signed int py){
 char z;
 unsigned char firePins=0;

    px--;
    for(z=7;z>=0;z--){
       px++;
       if (getpixel(px,py)==0||getpixel(px,py)==darkgray
	 || getpixel(px,py)==notcolor1
	   || getpixel(px,py)==notcolor2);/*do nout*/
       else firePins+=(char)pow(2,(float)z);
    }
    return firePins;
}

/****************************************************/
void printimage(char Land_Port,
      unsigned char notcolor1,unsigned char notcolor2,
	signed int x1,signed int y1,signed int x2, signed int y2){

 /*prints the image - landscape*/
 signed int px,py,width,height,
     tempx,tempy;
 unsigned char tempcolor;

   tempx=getx;
   tempy=gety;
   draw_hint_box(0,1,"printing scrn, stop-q:",vgax(500));
   setviewport(0, 0, getmaxx(), getmaxy(), 0); /*watcom*/

   tempcolor=getcolor();
   setcolor(red);
   line(0,getmaxy()-vgay(13),getmaxx(),getmaxy()-vgay(13));

   width=x2-x1;
   height=y2-y1+2;
   prn_putc(ESC);
   prn_putc('@');   /*initialise printer*/
   /*initialise line spacing to 7/72*/
   prn_putc(ESC);
   /*prn_putc('0');*/             /*for lq-570*/
   prn_putc(65);prn_putc(8);      /*for mx-82*/

   if (Land_Port=='L'){
      for (py=x1;py<x1+width;py+=8){
	 bitImage(height);
	 for (px=y1+height-1;px>=y1;px--)
	       prn_putc(getScrBits_Land(notcolor1,notcolor2,py,px));
	 prn_putc('\n');
	 /*interupt printing*/
	 if (keycheck(0)=='q') break;
      }
   }
   else{ /*P=Portrait*/
      for (py=y1;py<y1+height;py+=8){
	 bitImage(width);
	 for (px=x1; px<=x1+width-1; px++)
	       prn_putc(getScrBits_Port(notcolor1,notcolor2,px,py));
	 prn_putc('\n');
	 /*interupt printing*/
	 if (keycheck(0)=='q') break;
      }
   }
   erase_free_hint_box(vgax(500));
   setcolor(darkgray);
   line(0,getmaxy()-vgay(13),getmaxx(),getmaxy()-vgay(13));
   setcolor(tempcolor);
   setviewport(0, 0, Maxx, Maxy, 1); /*watcom*/
   moveto(tempx,tempy);
}

/******************* printout a string on printer *********************/
void print_out(char *array){
signed int z;
	z=0;
	/*initialise printer*/
	/*
	prn_putc(ESC);
	prn_putc('@');
	*/
	/*initialise line spacing to 7/72*/
	prn_putc(ESC);
	/*prn_putc('0');*/       /*for lq-570*/
	prn_putc(65);prn_putc(8);
	/*for mx-82, sets line spacing at 8 lines/in*/

	while (array[z] != '\0'){  /*prints to buffer until '\n' */
		prn_putc(array[z]);
	       z++;
	}
}
/******************************************************/
void print_option(void){

	   draw_prompt_box(1);
	   sprintf(textb[0],"IMAGE TO PRINTER ENTER p:");
	   outtext(textb[0]);
	   input_string(1,0);
	   if (is[0]=='q') return;

	   if(is[0]=='p'||is[0]=='P') select_print_style();

}
/******************************************************/
void select_print_style(void){
 char style;
 unsigned char notcolor1,notcolor2;

    notcolor1=notcolor2=0;
    style='l';
    draw_prompt_box(1);
    sprintf(textb[0],"enter portrait-p, landscape-default:");
    outtext(textb[0]);
    input_string(1,0);
    if (is[0]=='q') return;
    if (is[0]=='p'||is[0]=='P') style='p';
    else style='l';
    erase_prompt_box(1);
    if(style=='l')printimage('L',notcolor1,notcolor2,
				   0,0,getmaxx(),getmaxy());
    if(style=='p')printimage('P',notcolor1,notcolor2,
				   0,0,getmaxx(),getmaxy());
}

/************************** set up mouse **********************/
void mouse_call(regax,regbx,regcx,regdx){

	union REGS inregs,outregs;

	inregs.w.ax = regax;
	inregs.w.bx = regbx;
	inregs.w.cx = regcx;
	inregs.w.dx = regdx;

	int386(0x33,&inregs,&outregs);

	globax = outregs.w.ax;
	globbx = outregs.w.bx;
	globcx = outregs.w.cx;
	globdx = outregs.w.dx;

}

/****************  memory available - watcom *************/
unsigned long get_memory(void){
    /*
    MEMORY.C - This example shows how to get information
    about free memory using DPMI call 0500h under DOS/4GW.
    Note that only the first field of the structure is
    guaranteed to contain a valid value; any field that
    is not returned by DOS/4GW is set to -1 (0FFFFFFFFh).

    Compile & Link: wcl386 /l=dos4g memory
    */
    struct meminfo {
	unsigned LargestBlockAvail;
	unsigned MaxUnlockedPage;
	unsigned LargestLockablePage;
	unsigned LinAddrSpace;
	unsigned NumFreePagesAvail;
	unsigned NumPhysicalPagesFree;
	unsigned TotalPhysicalPages;
	unsigned FreeLinAddrSpace;
	unsigned SizeOfPageFile;
	unsigned Reserved[3];
    } MemInfo;

    #define DPMI_INT	0x31


    union REGS regs;
    struct SREGS sregs;

    regs.x.eax = 0x00000500;
    memset( &sregs, 0, sizeof(sregs) );
    sregs.es = FP_SEG( &MemInfo );
    regs.x.edi = FP_OFF( &MemInfo );

    int386x( DPMI_INT, &regs, &regs, &sregs );

    /*
    printf( "Maximum unlocked page allocation: %lu\n",
	    MemInfo.MaxUnlockedPage );
    printf( "Pages that can be allocated and locked: %lu\n",
	    MemInfo.LargestLockablePage );
    printf( "Total linear address space including allocated"
	    " pages: %lu\n", MemInfo.LinAddrSpace );
    printf( "Number of free pages available: %lu\n",
	     MemInfo.NumFreePagesAvail );
    printf( "Number of physical pages not in use: %lu\n",
	     MemInfo.NumPhysicalPagesFree );
    printf( "Total physical pages managed by host: %lu\n",
	     MemInfo.TotalPhysicalPages );
    printf( "Free linear address space (pages): %lu\n",
	     MemInfo.FreeLinAddrSpace );
    printf( "Size of paging/file partition (pages): %lu\n",
	     MemInfo.SizeOfPageFile );
    */
    return(MemInfo.LargestBlockAvail);
}
# endif
/*------------------------ end watcom graphics ---------------*/

