#define GLOBALORIGIN
#include "xgrafix.h"
#undef GLOBALORIGIN

/*****************************************************************/
/* XGrafix is a costomized environment to run in X11.            */
/* (c) Copyright 1992 The Regent of the University of California */
/* Version 1.0                                                   */
/* Authors:  Vahid Vahedi and John Verboncoeur                   */
/*****************************************************************/


/*****************************************************************/

void XGInit(int argc, char *argv[], double *t)   /* ddd */
{
  XColor theRGBColor, theHardwareColor;
  int    i=0;
  char   temp[60];

  theTimeStep = t;

  /*****************************************/
  /* Getting the code and input file names */

  sprintf(theCodeName, "%s", argv[0]);
 
  if(argc >1){
    strcpy(theInputFile, argv[1]);
    
    if(argc>2)
    {
      strcpy(temp, argv[2]);
      if(access(temp, F_OK)) strcat(temp, theDumpExtension);
    }
    if(argc>2 && !access(temp, F_OK))
    {
      for(i=strlen(temp)-1; i>0; i--) if(temp[i] == '.') break;
      if(i){
	strncpy(theDumpFile, temp, i);
	strncpy(thePSFile, temp, i);
      } else {
	strcpy(theDumpFile, temp);
	strcpy(thePSFile, temp);
      }
    } 
    else
    {
      for(i=strlen(theInputFile)-1; i>0; i--)
	if(theInputFile[i] == '.') break;
      if(i){
	strncpy(theDumpFile, theInputFile, i);
	strncpy(thePSFile, theInputFile, i);
      } else {
	strcpy(theDumpFile, theInputFile);
	strcpy(thePSFile,   theInputFile);
      }
    }
    strcat(theDumpFile, theDumpExtension);
    strcat(thePSFile,   thePSExtension);
  }
  else
  {
    strcpy(theInputFile, "No Input File");
    strcpy(theDumpFile, theDefaultDumpFile);
    strcpy(thePSFile,   theDefaultPSFile);
  }
  /**********************/
  /* The disclaimer..   */

  puts("\nXGrafix version 1.0");
  puts("(c) Copyright 1992 The Regents of the University of California");
  puts("Authors:  Vahid Vahedi and John Verboncoeur\n");

  /*********************************/
  /* Get the Display information   */

  theDisplay = XOpenDisplay(ReqDisp);

  if (theDisplay == NULL) 
  {
    fprintf(stderr, "XGrafix: Cannot establish connection to the XServer %s\n",
	    XDisplayName(NULL));
    exit(1);
  }

  theScreen = DefaultScreen(theDisplay);
  theDepth  = DefaultDepth(theDisplay, theScreen);

  theBlackPixel = BlackPixel(theDisplay, theScreen);
  theWhitePixel = WhitePixel(theDisplay, theScreen);

  theColormap   = DefaultColormap(theDisplay, theScreen);
  theRootWindow = RootWindow(theDisplay, theScreen);

  theDisplayWidth = DisplayWidth(theDisplay,theScreen);
  theDisplayHeight= DisplayHeight(theDisplay,theScreen);

  printf("XGrafix is running on %s version %d of the X Window System, X%d R%d\n",
	 ServerVendor(theDisplay), VendorRelease(theDisplay),
	 ProtocolVersion(theDisplay), ProtocolRevision(theDisplay));
  
 /* ddd: do we really need this information?
  if (theDepth == 1) 
    printf("Color plane depth ......... %d (monochrome)\n",theDepth);
  else
    printf("Color plane depth ......... %d\n", theDepth);
  
  printf("Display width ............. %d\n", theDisplayWidth);
  printf("Display height ............ %d\n", theDisplayHeight);
  printf("The display %s\n\n", XDisplayName(theDisplay));
 */
  
  /****************************/
  /* Initializing the colors  */

  if (theDepth > 1)
  {
    for (i =0; i <MAXCOLORS; i++) 
    {
      if(XLookupColor(theDisplay, theColormap, theColorNames[i], &theRGBColor, &theHardwareColor))
      	if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) Color[i] = theHardwareColor.pixel;
    }
    if(XLookupColor(theDisplay, theColormap, WindowTextColor, &theRGBColor, &theHardwareColor))
      if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) theWinTextColor = theHardwareColor.pixel;
    
    if(XLookupColor(theDisplay, theColormap, DialogBoxTextColor, &theRGBColor, &theHardwareColor))
      if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) theDBTextColor  = theHardwareColor.pixel;
    
    if(XLookupColor(theDisplay, theColormap, BorderColor, &theRGBColor, &theHardwareColor))
      if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) theBorderColor  = theHardwareColor.pixel;
    
    if(XLookupColor(theDisplay, theColormap, TickMarkColor, &theRGBColor, &theHardwareColor))
      if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) theTickMarkColor= theHardwareColor.pixel;
    
    if(XLookupColor(theDisplay, theColormap, BackgroundColor, &theRGBColor, &theHardwareColor))
      if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) theBKGDColor= theHardwareColor.pixel;
    
    for (i =0; i <MAXGRAYSHADES; i++) 
    {
      if(XLookupColor(theDisplay, theColormap, theGrayShades[i], &theRGBColor, &theHardwareColor))
      	if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) GrayShade[i] = theHardwareColor.pixel;
    }   

    /************* the ThreeD Colors ***************/
    for (i=0; i <=60; i++) 
    { 
      if(0 <= i && i < 10)
	sprintf(temp, "#%s%s%s", theTDColorNames[10], theTDColorNames[i], theTDColorNames[0]);
      else if(10 <= i && i < 20)
	sprintf(temp, "#%s%s%s", theTDColorNames[20-i], theTDColorNames[10], theTDColorNames[0]);
      else if(20 <= i && i < 30)
	sprintf(temp, "#%s%s%s", theTDColorNames[0], theTDColorNames[10], theTDColorNames[i-20]);
      else if(30 <= i && i < 40)
	sprintf(temp, "#%s%s%s", theTDColorNames[0], theTDColorNames[40-i], theTDColorNames[10]);
      else if(40 <= i && i < 50)
	sprintf(temp, "#%s%s%s", theTDColorNames[i-40], theTDColorNames[0], theTDColorNames[10]);
      else if(50 <= i && i < 60)
	sprintf(temp, "#%s%s%s", theTDColorNames[10], theTDColorNames[i-50], theTDColorNames[10]);
      else if(i == 60)
	sprintf(temp, "#%s%s%s", theTDColorNames[10], theTDColorNames[10], theTDColorNames[10]);

     /*  sprintf(temp, "#%x%x%x", 64+3*i, 64+3*i, 64+3*i); */
        
      if(XParseColor(theDisplay, theColormap, temp, &theHardwareColor))
      	if(XAllocColor(theDisplay, theColormap, &theHardwareColor)) ThreeDColor[i] = theHardwareColor.pixel;
    }
  }
  else
  { 
    for (i = 0; i < MAXCOLORS; i++) Color[i]= theWhitePixel;
    for (i = 0; i < MAXTHREEDCOLORS; i++) ThreeDColor[i]= theWhitePixel;
    theWinTextColor = theWhitePixel;
    theDBTextColor  = theWhitePixel;
    theBorderColor  = theWhitePixel;
    theTickMarkColor=  theWhitePixel;
    theBKGDColor    = theBlackPixel;
  
    for (i =0; i <MAXGRAYSHADES; i++) GrayShade[i]= theWhitePixel;
    GrayShade[1]= theBlackPixel;
    GrayShade[3]= theBlackPixel;
    GrayShade[5]= theBlackPixel;
    GrayShade[6]= theBlackPixel;
    GrayShade[10]=theBlackPixel;
  }
  
  /************************************/
  /* Initializing the XGrafix font    */
  
  if((theFontStruct = XLoadQueryFont(theDisplay, theFontName)) == NULL)
  {
    printf("can't open the specified font\n");
    exit(-1);
  }
  theFont       = theFontStruct->fid;
  theFontAscent = theFontStruct->ascent;
  theFontDescent= theFontStruct->descent;
  theFontHeight = theFontAscent + theFontDescent;

  /*****************************/
  /* Initializing the cursors  */

  theButtonCursor    = XCreateFontCursor(theDisplay, BUTTONCURSOR);
  theCrosshairCursor = XCreateFontCursor(theDisplay, CROSSHAIRCURSOR);

  /*****************************/
  /* Initializing the sounds   */
  
  strcpy(Sound1, "cat ");
  strcat(Sound1, path);
  strcat(Sound1, "/xgrafix.sd1 > ");
  strcat(Sound1, speaker);

  strcpy(Sound2, "cat ");
  strcat(Sound2, path);
  strcat(Sound2, "/xgrafix.sd2 > ");
  strcat(Sound2, speaker);

  strcpy(Sound3, "cat ");
  strcat(Sound3, path);
  strcat(Sound3, "/xgrafix.sd3 > ");
  strcat(Sound3, speaker);

  strcpy(Sound4, "cat ");
  strcat(Sound4, path);
  strcat(Sound4, "/xgrafix.sd4 > ");
  strcat(Sound4, speaker);

  /************************************/
  /* Initializing the XGrafix icon    */

  theIcon = XCreateBitmapFromData(theDisplay, theRootWindow,xgrafix_bits,
				  xgrafix_width, xgrafix_height);
  theIconULX= 2;
  theIconULY= theDisplayHeight -40;

  /********************************/
  /* Initializing the main menu   */

  theRunFlag = False;
  theStepFlag= False;
  Init_Main_Menu();

  /**********************************************************/
  /* Initializing the dialog boxs and the related variables */

  Init_DF_DialogBox();
  Init_PS_DialogBox();
  Init_Rescale_DialogBox();
  Init_Message_DialogBox();
  Init_ThreeDView_DialogBox();

  init_theta = init_phi = 45;
  
  theOpenDialogBox       = NULL;
  theOpenDialogBoxWindow = NULL; 
  theDialogBoxButtonLabelX = 10;
  theDialogBoxButtonLabelY = 2*(theFontHeight +10) +theFontAscent;
  theDialogBoxButtonSpacing= theFontHeight+28;

  theCrosshairedWindow   = NULL;

  /*************************************/
  /* Initializing the window link list */

  theWindowList = NULL;
}

/*****************************************************************/

void XGEvent()
{
  while(!theStepFlag && !theRunFlag) Event_Manager();
}

/*****************************************************************/

void XGUpdate()
{
  Refresh_Screen(); Event_Manager();
}

/*****************************************************************/

XGSet2D(PlotType, X_Label, Y_Label, State, ulx, uly, X_Scale, Y_Scale,
        X_Auto_Rescale, Y_Auto_Rescale, X_Min, X_Max, Y_Min, Y_Max)
char  *PlotType;          /* "linlin", "linlog", "loglog", or "loglin"        */
char  *X_Label;           /* x label for the frame                            */
char  *Y_Label;           /* y label for the frame                            */
float  X_Scale;           /* scaling factor for the x array                   */
float  Y_Scale;           /* scaling factor for the y array                   */
char  *State;             /* "open" or "iconic"                               */
int    ulx, uly;          /* requested position of frame's upper left coner   */
int    X_Auto_Rescale;    /* if True X_Min and X_Max are neglected            */
int    Y_Auto_Rescale;    /* if True Y_Min and Y_Max are neglected            */
float  X_Min, X_Max;      /* x bounds for the plot if x-autorescale if False  */
float  Y_Min, Y_Max;      /* y bounds for the plot if y-autorescale if False  */
{
  int plottype, state;

  DataType data_ptr=NULL;
  LabelType label_ptr;

  label_ptr  = SetupLabelStruct();
  label_ptr->Y_Label       = Y_Label;
  label_ptr->Y_Min         = Y_Min;
  label_ptr->Y_Max         = Y_Max;
  label_ptr->Y_Scale       = Y_Scale;
  label_ptr->Y_Auto_Rescale= Y_Auto_Rescale;

  label_ptr->X_Label       = X_Label;
  label_ptr->X_Min         = X_Min;
  label_ptr->X_Max         = X_Max;
  label_ptr->X_Scale       = X_Scale;
  label_ptr->X_Auto_Rescale= X_Auto_Rescale;

  if(!strcmp(PlotType, "linlin"))      plottype= LIN_LIN;
  else if(!strcmp(PlotType, "linlog")) plottype= LIN_LOG;
  else if(!strcmp(PlotType, "loglog")) plottype= LOG_LOG;
  else if(!strcmp(PlotType, "loglin")) plottype= LOG_LIN;
  else
  {
    printf("Unrecognized plot string '%s' for Window '%s'.\n", PlotType, Y_Label);
    exit(-1);
  }
  
  if(!strcmp(State, "open"))        state= OPEN_STATE;
  else if(!strcmp(State, "iconic")) state= ICONIC_STATE;
  else
  {
    printf("Unrecognized state string '%s' for Window '%s'.\n", State, Y_Label);
    exit(-1);
  }
  
  SetupWindow(TWOD, plottype, label_ptr, data_ptr, state, ulx, uly);

  return(1);           /* ddd: just against warnings */
}

/***********************************************************************/  

      /* ddd: was XGSet2DC - ? */

/***********************************************************************/  

XGSet3D(PlotType, X_Label, Y_Label, Z_Label, Theta, Phi, State, ulx, uly,
	X_Scale, Y_Scale, Z_Scale, X_Auto_Rescale, Y_Auto_Rescale,
	Z_Auto_Rescale, X_Min, X_Max, Y_Min, Y_Max, Z_Min, Z_Max)
char  *PlotType;          /* "linlinlin", "linlinlog", "linloglog", etc.      */
char  *X_Label;           /* x label for the frame                            */
char  *Y_Label;           /* y label for the frame                            */
char  *Z_Label;           /* z label for the frame                            */
float  Theta, Phi;        /* initial viewing angles                           */
char  *State;             /* "open" or "iconic"                               */
int    ulx, uly;          /* requested position of frame's upper left coner   */
float  X_Scale;           /* scaling factor for the x array                   */
float  Y_Scale;           /* scaling factor for the y array                   */
float  Z_Scale;           /* scaling factor for the z array                   */
int    X_Auto_Rescale;    /* if True X_Min and X_Max are neglected            */
int    Y_Auto_Rescale;    /* if True Y_Min and Y_Max are neglected            */
int    Z_Auto_Rescale;    /* if True Z_Min and Z_Max are neglected            */
float  X_Min, X_Max;      /* x bounds for the plot if x-autorescale if False  */
float  Y_Min, Y_Max;      /* y bounds for the plot if y-autorescale if False  */
float  Z_Min, Z_Max;      /* z bounds for the plot if z-autorescale if False  */
{
  int plottype, state;

  DataType data_ptr=NULL;
  LabelType label_ptr;

  init_theta= Theta;
  init_phi  = Phi;

  label_ptr  = SetupLabelStruct();
  label_ptr->Z_Label       = Z_Label;
  label_ptr->Z_Min         = Z_Min;
  label_ptr->Z_Max         = Z_Max;
  label_ptr->Z_Scale       = Z_Scale;
  label_ptr->Z_Auto_Rescale= Z_Auto_Rescale;
  
  label_ptr->Y_Label       = Y_Label;
  label_ptr->Y_Min         = Y_Min;
  label_ptr->Y_Max         = Y_Max;
  label_ptr->Y_Scale       = Y_Scale;
  label_ptr->Y_Auto_Rescale= Y_Auto_Rescale;

  label_ptr->X_Label       = X_Label;
  label_ptr->X_Min         = X_Min;
  label_ptr->X_Max         = X_Max;
  label_ptr->X_Scale       = X_Scale;
  label_ptr->X_Auto_Rescale= X_Auto_Rescale;

  if(!strcmp(PlotType, "linlinlin"))      plottype= LIN_LIN_LIN;
  else if(!strcmp(PlotType, "linlinlog")) plottype= LIN_LIN_LOG;
  else if(!strcmp(PlotType, "linloglin")) plottype= LIN_LOG_LIN;
  else if(!strcmp(PlotType, "linloglog")) plottype= LIN_LOG_LOG;
  else if(!strcmp(PlotType, "loglinlin")) plottype= LOG_LIN_LIN;
  else if(!strcmp(PlotType, "loglinlog")) plottype= LOG_LIN_LOG;
  else if(!strcmp(PlotType, "logloglin")) plottype= LOG_LOG_LIN;
  else if(!strcmp(PlotType, "logloglog")) plottype= LOG_LOG_LOG;
  else
  {
    printf("Unrecognized plot string '%s' for Window '%s'.\n", PlotType, Z_Label);
    exit(-1);
  }
  
  if(!strcmp(State, "open"))        state= OPEN_STATE;
  else if(!strcmp(State, "iconic")) state= ICONIC_STATE;
  else
  {
    printf("Unrecognized state string '%s' for Window '%s'.\n", State, Z_Label);
    exit(-1);
  }
  
  SetupWindow(THREED, plottype, label_ptr, data_ptr, state, ulx, uly);
  
    return(1);           /* ddd: just against warnings */
}

/***********************************************************************/  

void XGCurve(float *x_array, float *y_array, int *npoints, int color)
/*   *x_array;     x_array to be plotted            ddd           */
/*   *y_array;     y_array to be plotted                          */
/*     *npoints;     number of points in the x (and y) direction    */
/*      color;       plot's color chosen from 0-9                   */
{
  DataType data_prevptr, data_ptr;

  data_prevptr     = theWindowList->data;  
  data_ptr         = SetupDataStruct();
  data_ptr->y      = y_array;
  data_ptr->x      = x_array;
  data_ptr->npoints= npoints;
  data_ptr->color  = Color[color];
  data_ptr->next   = data_prevptr;

  theWindowList->data= data_ptr;
}

/***********************************************************************/  

void XGScat2D(float *x_array, float *y_array, int *npoints, int color)
/*   *x_array;     x_array to be plotted           ddd            */
/*   *y_array;     y_array to be plotted                          */
/*     *npoints;     number of points in the x (and y) direction    */
/*      color;       plot's color chosen from 0-9                   */
{
  DataType data_prevptr, data_ptr;

  data_prevptr     = theWindowList->data;  
  data_ptr         = SetupDataStruct();
  data_ptr->y      = y_array;
  data_ptr->x      = x_array;
  data_ptr->npoints= npoints;
  data_ptr->color  = Color[color];
  data_ptr->next   = data_prevptr;
  Set_Scatter(data_ptr);

  theWindowList->data= data_ptr;
}

/***********************************************************************/

void XGScat3D(float *x_array, float *y_array, float *z_array, int *npoints, int color)
/*   *x_array;     x_array to be plotted            ddd           */
/*   *y_array;     y_array to be plotted                          */
/*   *z_array;     z_array to be plotted                          */
/*     *npoints;     number of points in the x, y and z direction   */
/*      color;       plot's color chosen from 0-9                   */
{
  DataType data_prevptr, data_ptr;
  
  data_prevptr     = theWindowList->data;  
  data_ptr         = SetupDataStruct();
  data_ptr->zscat  = z_array;
  data_ptr->y      = y_array;
  data_ptr->x      = x_array;
  data_ptr->npoints= npoints;
  data_ptr->color  = Color[color];
  data_ptr->next   = data_prevptr;
  Set_Scatter(data_ptr);
  
  theWindowList->data= data_ptr;
}

/***********************************************************************/  

void XGSurf(float *x_array, float *y_array, float **z_array, int *mpoints, int *npoints, int color)
/*   *x_array;     x_array to be plotted         ddd              */
/*   *y_array;     y_array to be plotted                          */
/*   *z_array;     z_array to be plotted                          */
/*     *mpoints;     number of points in the x direction            */
/*     *npoints;     number of points in the y direction            */
/*      color;       plot's color chosen from 0-9                   */
{
  DataType data_prevptr, data_ptr;

  data_prevptr     = theWindowList->data;  
  data_ptr         = SetupDataStruct();
  data_ptr->z      = z_array;
  data_ptr->y      = y_array;
  data_ptr->x      = x_array;
  data_ptr->mpoints= mpoints;
  data_ptr->npoints= npoints;
  data_ptr->color  = Color[color];
  data_ptr->next   = data_prevptr;
  
  theWindowList->data= data_ptr;
}

/***********************************************************************/  

void XGCont(float *x_array, float *y_array, float **z_array, int *mpoints, int *npoints, int color)
/*   *x_array;     x_array to be plotted                          */
/*   *y_array;     y_array to be plotted                          */
/*  **z_array;     z_array to be plotted                          */
/*     *mpoints;     number of points in the x direction            */
/*     *npoints;     number of points in the y direction            */
/*      color;       plot's color chosen from 0-9                   */

{
  DataType data_prevptr, data_ptr;

  data_prevptr     = theWindowList->data;  
  data_ptr         = SetupDataStruct();
  data_ptr->z      = z_array;
  data_ptr->y      = y_array;
  data_ptr->x      = x_array;
  data_ptr->mpoints= mpoints;
  data_ptr->npoints= npoints;
  data_ptr->color  = Color[color];
  data_ptr->next   = data_prevptr;
  
  theWindowList->data= data_ptr;
}
/***********************************************************************/

/* Here were FORTRAN callable routines. ddd  */

/***********************************************************************/

DataType SetupDataStruct()
{
  DataType data;
  
  if (!(data= (DataType)malloc(sizeof(struct data)))) putchar(7);
  
  data->z      = NULL;
  data->zscat  = NULL;
  data->y      = NULL;
  data->x      = NULL;
  data->mpoints= 0;
  data->npoints= 0;
  data->color  = 0;
  data->next   = NULL;

  return(data);
}

/****************************************************************/

LabelType SetupLabelStruct()
{
  LabelType label;
  
  if (!(label= (LabelType)malloc(sizeof(struct label)))) putchar(7);
  
  label->Z_Scale        = 1;
  label->Z_Min          = 0;
  label->Z_Max          = 0;
  label->Z_Label        = NULL;
  label->Z_Auto_Rescale = True;

  label->Y_Scale        = 1;
  label->Y_Min          = 0;
  label->Y_Max          = 0;
  label->Y_Label        = NULL;
  label->Y_Auto_Rescale = True;

  label->X_Scale        = 1;
  label->X_Min          = 0;
  label->X_Max          = 0;
  label->X_Label        = NULL;
  label->X_Auto_Rescale = True;
 
  return(label);
}

/***********************************************************************/  

void SetupWindow(int WINTYPE, int PLOTTYPE, LabelType label_ptr,
        DataType data_ptr, int STATE, int ulx, int uly)
/*   WINTYPE;          Window Type: TWOD or THREED           ddd        */
/*    PLOTTYPE;        LIN_LIN, LIN_LOG, LOG_LOG, or LOG_LIN            */
/*  label_ptr;    Contains all the info about the labels           */
/*  data_ptr;     Contains all the info about data being plotted   */
/*   STATE;            OPEN_STATE or ICONIC_STATE                       */
/*   ulx, uly;         the requested position of the upper left coner   */
{
  XSetWindowAttributes  theWindowAttributes;
  XSizeHints            theSizeHints;
  unsigned long         theWindowMask;
  WindowType            theNewWindow;
  int                   theButtonNumber;
  ButtonType            theButtonListPtr, theButtonListPrevPtr;
  XWMHints              theWMHints;
  XGCValues             theGCValues;
  int                   i, l, offset=0;

  if (!(theNewWindow = (WindowType)malloc(sizeof(struct window_struct))))
  { 
    putchar(7);
    puts("XGrafix(SetupWindow): Not enough memory to allocate a new window");
  }

  theNewWindow->state = 0;
  theNewWindow->data  = data_ptr;
  theNewWindow->label = label_ptr;
  theNewWindow->theta = init_theta;
  theNewWindow->phi   = init_phi;
  theNewWindow->next  = theWindowList;
  theWindowList       = theNewWindow;
  strcpy(theNewWindow->ps_file_name, thePSFile);

  if (WINTYPE == THREED)
  {
    theNewWindow->width = DEFAULT_THREED_WIN_WIDTH;
    theNewWindow->height= DEFAULT_THREED_WIN_HEIGHT;
    strcpy(theNewWindow->plot_title, label_ptr->Z_Label);
  }
  else
  {
    theNewWindow->width = DEFAULT_WIN_WIDTH;
    theNewWindow->height= DEFAULT_WIN_HEIGHT;
    strcpy(theNewWindow->plot_title, label_ptr->Y_Label);
  }

  /****************************************************/
  /* Setting the windiw's attributes and creating it  */

  theWindowAttributes.border_pixel      = theWhitePixel;
  theWindowAttributes.background_pixel  = GrayShade[3];
  theWindowMask = (CWBackPixel | CWBorderPixel);

  theNewWindow->xwin = XCreateWindow(theDisplay, theRootWindow, ulx, uly,
				     theNewWindow->width, theNewWindow->height,
				     DEFAULT_WIN_BORDER_WIDTH, theDepth,
				     InputOutput, CopyFromParent,
				     theWindowMask, &theWindowAttributes);

  /**************************************/
  /* Setting the window manager's hints */

  if (STATE == OPEN_STATE)
    theWMHints.initial_state = NormalState;
  else 
    theWMHints.initial_state = IconicState;

  if(theIconULX +8.5*max(strlen(label_ptr->Y_Label), 10) > theDisplayWidth)
  {
    theIconULX  =  2;
    theIconULY -= 40;
  }
  
  theWMHints.icon_pixmap = theIcon;
  theWMHints.icon_x      = theIconULX;
  theWMHints.icon_y      = theIconULY;
  theWMHints.flags       = IconPixmapHint | StateHint | IconPositionHint;
  
  XSetWMHints(theDisplay, theNewWindow->xwin, &theWMHints);
  if (WINTYPE == THREED)
    XStoreName(theDisplay, theNewWindow->xwin, label_ptr->Z_Label);
  else
    XStoreName(theDisplay, theNewWindow->xwin, label_ptr->Y_Label);

  theIconULX += 8.5*max(strlen(label_ptr->Y_Label), 10);
  
  /****************************************/
  /* Setting the size and normal hints    */

  theSizeHints.flags  = USPosition | USSize;
  theSizeHints.x      = ulx;
  theSizeHints.y      = uly;
  theSizeHints.width  = theNewWindow->width;
  theSizeHints.height = theNewWindow->height;
  
  XSetNormalHints( theDisplay, theNewWindow->xwin, &theSizeHints);
  
  /***************************************/
  /* Initializing a GC for the window    */

  theNewWindow->xwingc = XCreateGC(theDisplay, theNewWindow->xwin,
				   (unsigned long) 0, &theGCValues);
  if (theNewWindow->xwingc)
  {
    XSetForeground(theDisplay, theNewWindow->xwingc, theWhitePixel);
    XSetBackground(theDisplay, theNewWindow->xwingc, theBlackPixel);
  }
  else
  {
    printf("XGrafix: can't create a GC for the %s window.", label_ptr->Y_Label);
    XDestroyWindow(theDisplay, theNewWindow->xwin);
  }
  
  XSelectInput(theDisplay, theNewWindow->xwin, 
	       StructureNotifyMask | SubstructureNotifyMask | ButtonPressMask | ExposureMask);

  /******************************************/
  /* Initializing the Pixmap for the window */
  
  theNewWindow->pixmap_buffer = NULL;
  
  /*********************************************/
  /* Setting the font type used in the window */

  XSetFont(theDisplay, theNewWindow->xwingc, theFont);

  /********************************************/
  /* Setting up the buttons for the window    */

  if (WINTYPE == THREED) theButtonNumber = MAX_3D_WIN_BUTTON;
  else                   theButtonNumber = MAX_2D_WIN_BUTTON;
  
  theButtonListPrevPtr = NULL;
  for(i=0; i< theButtonNumber; i++)
  {
    if (!(theButtonListPtr = (ButtonType)malloc(sizeof(struct win_button))))
      puts("XGrafix(SetupWindow): Not enough memory to allocate a new button");

    theButtonListPtr->state = NORMAL_STATE;
    if(i==0)
    { sprintf(theButtonListPtr->Label, "%s", "Rescale");   theButtonListPtr->id = WINDOW_MENU_RESCALE;
    }
    else if(i==1)
    { sprintf(theButtonListPtr->Label, "%s", "Trace");     theButtonListPtr->id = WINDOW_MENU_TRACE;
    }
    else if(i==2)
    { sprintf(theButtonListPtr->Label, "%s", "Print");     theButtonListPtr->id = WINDOW_MENU_PRINT;
    }
    else if(i==3)
    { sprintf(theButtonListPtr->Label, "%s", "Crosshair"); theButtonListPtr->id = WINDOW_MENU_CROSSHAIR;
    }
    else if(i==4)
    { sprintf(theButtonListPtr->Label, "%s", "3D View");   theButtonListPtr->id = WINDOW_MENU_3D_VIEW;
    }
    
    l = strlen(theButtonListPtr->Label);
    theButtonListPtr->xwin  = XCreateSimpleWindow(theDisplay, theNewWindow->xwin, offset, 0,
						  XTextWidth(theFontStruct, theButtonListPtr->Label, l)+18,
						  theFontHeight+16, 1, GrayShade[5], theBlackPixel);

    if ((i == 1 || i == 3) && WINTYPE == THREED)
    {
      theButtonListPtr->state = GRAYED_STATE;
      XSelectInput(theDisplay, theButtonListPtr->xwin, ExposureMask);
    }
    else
    {
      XSelectInput(theDisplay, theButtonListPtr->xwin,
		   ButtonPressMask | ButtonReleaseMask | ExposureMask);
      XDefineCursor(theDisplay, theButtonListPtr->xwin, theButtonCursor);
    }
    
    theButtonListPtr->xwingc = XCreateGC(theDisplay, theButtonListPtr->xwin,
					 (unsigned long) 0, &theGCValues);
    
    XSetFont(theDisplay, theButtonListPtr->xwingc, theFont);
    
    offset += XTextWidth(theFontStruct, theButtonListPtr->Label, l)+22;
    theButtonListPtr->next= theButtonListPrevPtr;
    theButtonListPrevPtr = theButtonListPtr;
  }
  theNewWindow->button_list = theButtonListPtr;
  if (WINTYPE == THREED)
  {
    theNewWindow->ulxc = offset;
    theNewWindow->ulyc = theFontHeight+16;
  }
  XMapSubwindows(theDisplay, theNewWindow->xwin);

  /****************************************************/
  /* Setting the window type and the other state-bits */

  if (WINTYPE == TWOD)
  {
    theNewWindow->paint_function = Paint_Window;
    theNewWindow->print_function = PostScriptOpenWindow;
  }
  else
  {
    Set_ThreeD(theNewWindow);
    ColorCode_On(theNewWindow);
    Grid_On(theNewWindow);
    theNewWindow->paint_function = Paint_ThreeD_Window;
    theNewWindow->print_function = PostScript_ThreeD_Window;
  }
  if(WINTYPE == TWOD)
  {
    if(PLOTTYPE == LOG_LIN || PLOTTYPE == LOG_LOG) Set_X_Log(theNewWindow);
    if(PLOTTYPE == LIN_LOG || PLOTTYPE == LOG_LOG) Set_Y_Log(theNewWindow);
  }
  else if(WINTYPE == THREED)
  {
    if(PLOTTYPE == LOG_LIN_LIN || PLOTTYPE == LOG_LIN_LOG ||
       PLOTTYPE == LOG_LOG_LIN || PLOTTYPE == LOG_LOG_LOG) Set_X_Log(theNewWindow);
    if(PLOTTYPE == LIN_LOG_LIN || PLOTTYPE == LIN_LOG_LOG ||
       PLOTTYPE == LOG_LOG_LIN || PLOTTYPE == LOG_LOG_LOG) Set_Y_Log(theNewWindow);
    if(PLOTTYPE == LIN_LIN_LOG || PLOTTYPE == LIN_LOG_LOG ||
       PLOTTYPE == LOG_LIN_LOG || PLOTTYPE == LOG_LOG_LOG) Set_Z_Log(theNewWindow);
  }
  if (label_ptr->Z_Auto_Rescale) Z_AutoRescale(theNewWindow);  
  if (label_ptr->Y_Auto_Rescale) Y_AutoRescale(theNewWindow); 
  if (label_ptr->X_Auto_Rescale) X_AutoRescale(theNewWindow);  
  
  if (STATE == OPEN_STATE) Open(theNewWindow);
  else                     Iconify(theNewWindow);
  
  XMapWindow(theDisplay, theNewWindow->xwin);
}

/****************************************************************/

void Init_Main_Menu()
{
  XSetWindowAttributes  theWindowAttributes;
  XSizeHints            theSizeHints;
  unsigned long         theWindowMask;
  XWMHints              theWMHints;
  XGCValues             theGCValues;
  ButtonType            theButtonListPtr, theButtonListPrevPtr;
  int                   i;

  /*******************************************************/
  /* Setting the main menu's attributes and creating it  */

  theWindowAttributes.border_pixel      = theWhitePixel;
  theWindowAttributes.background_pixel  = theBlackPixel;
  theWindowMask = (CWBackPixel | CWBorderPixel);

  theMainMenu.xwin = XCreateWindow(theDisplay, theRootWindow, DEFAULT_MAIN_MENU_X,
				   DEFAULT_MAIN_MENU_Y, DEFAULT_MAIN_MENU_WIDTH,
				   MAX_MAIN_MENU_BUTTON*(theFontHeight+19),
				   DEFAULT_WIN_BORDER_WIDTH, theDepth,
				   InputOutput, CopyFromParent,
				   theWindowMask, &theWindowAttributes);
  
  /********************************************************/
  /* Setting the window manager's hints for the main menu */
  
  theWMHints.initial_state = NormalState;
  theWMHints.icon_pixmap   = theIcon;
  theWMHints.icon_x        = theIconULX;
  theWMHints.icon_y        = theIconULY;
  theWMHints.flags         = IconPixmapHint | StateHint | IconPositionHint;
 
  XSetWMHints(theDisplay, theMainMenu.xwin, &theWMHints);

  /*********************************/
  /* Setting the main menu's name  */

  XStoreName(theDisplay, theMainMenu.xwin, strcat(theCodeName, " Control Panel"));
  theIconULX+= 9*max(strlen(theCodeName), 10);

  /****************************************/
  /* Setting the size and normal hints    */

  theSizeHints.flags  = USPosition | USSize;
  theSizeHints.x      = DEFAULT_MAIN_MENU_X;
  theSizeHints.y      = DEFAULT_MAIN_MENU_Y;
  theSizeHints.width  = DEFAULT_MAIN_MENU_WIDTH;
  theSizeHints.height = MAX_MAIN_MENU_BUTTON*(theFontHeight+19);
  
  XSetNormalHints(theDisplay, theMainMenu.xwin, &theSizeHints);
  
  XSelectInput(theDisplay, theMainMenu.xwin,
	       StructureNotifyMask | ExposureMask | SubstructureNotifyMask);

  /********************************************/
  /* Setting up the buttons for the main menu */

  theButtonListPrevPtr = NULL;
  for(i=0; i< MAX_MAIN_MENU_BUTTON; i++)
  {
    if (!(theButtonListPtr = (ButtonType)malloc(sizeof(struct win_button))))
      puts("XGrafix(Init_Main_Menu): Not enough memory to allocate a new button");
    
    theButtonListPtr->state = NORMAL_STATE;
    if(i==0) sprintf(theButtonListPtr->Label, "Time = %lG", *theTimeStep);
    else if(i==1)
    { sprintf(theButtonListPtr->Label, "%s", "Run");   theButtonListPtr->id = MAIN_MENU_RUN;
    }
    else if(i==2)
    { sprintf(theButtonListPtr->Label, "%s", "Stop");  theButtonListPtr->id = MAIN_MENU_STOP;
    }
    else if(i==3)
    { sprintf(theButtonListPtr->Label, "%s", "Step");  theButtonListPtr->id = MAIN_MENU_STEP;
    }
    else if(i==4)
    { sprintf(theButtonListPtr->Label, "%s", "Save");  theButtonListPtr->id = MAIN_MENU_SAVE;
    }
    else if(i==5)
    { sprintf(theButtonListPtr->Label, "%s", "Quit");  theButtonListPtr->id = MAIN_MENU_QUIT;
    }

    theButtonListPtr->xwin  = XCreateSimpleWindow(theDisplay, theMainMenu.xwin,
						  0, i*(theFontHeight+19),
						  DEFAULT_MAIN_MENU_WIDTH-2,
						  theFontHeight+16, 1,
						  GrayShade[5], theBlackPixel);
    if(i==0)
    {
      theTimeStepButtonPtr = theButtonListPtr;
      theButtonListPtr->state = PUSHED_STATE;
      XSelectInput(theDisplay, theButtonListPtr->xwin, ExposureMask);
    }
    else
    {
      XSelectInput(theDisplay, theButtonListPtr->xwin,
		   ButtonPressMask | ButtonReleaseMask | ExposureMask);
      XDefineCursor(theDisplay, theButtonListPtr->xwin, theButtonCursor);
    }
    theButtonListPtr->xwingc = XCreateGC(theDisplay, theButtonListPtr->xwin,
					 (unsigned long) 0, &theGCValues);
    
    XSetFont(theDisplay, theButtonListPtr->xwingc, theFont);
    
    theButtonListPtr->next= theButtonListPrevPtr;
    theButtonListPrevPtr = theButtonListPtr;
  }
  theMainMenu.button_list = theButtonListPtr;
  
  XMapSubwindows(theDisplay, theMainMenu.xwin);
  XMapWindow(theDisplay, theMainMenu.xwin);
}

/*****************************************************************/

void Event_Manager()
{
  if(theStepFlag) theStepFlag =0;
  if(theRunFlag)
    while(XPending(theDisplay)) Process_One_Event();
  else                          Process_One_Event();
}

/*****************************************************************/

void Process_One_Event()
{
  XEvent        theEvent;
  int           i, j, doneFlag;
  WindowType    theWindowPtr;
 /* ddd not used:  Window        thePushedButton; */
  static Window thePrevExposedWindow=0;
  ButtonType    theButtonPtr;
  unsigned int  button;
  
  doneFlag =1;
  XNextEvent(theDisplay, &theEvent);
  switch (theEvent.type)
  {
    /************************/
  case MapNotify:
    for(theWindowPtr = theWindowList; theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
      if (theWindowPtr->xwin == theEvent.xmap.window)
      {
	Open(theWindowPtr);
	if(theWindowPtr->pixmap_buffer)
	{
	  XFreePixmap(theDisplay, theWindowPtr->pixmap_buffer);
	  theWindowPtr->pixmap_buffer = NULL;
	}
	Iconic_Before(theWindowPtr);
	break;
      }
    thePrevExposedWindow=0;
    break;

    /************************/
  case UnmapNotify:
    for(theWindowPtr = theWindowList; theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
      if (theWindowPtr->xwin == theEvent.xmap.window)
      {
	if(theWindowPtr->pixmap_buffer)
	{
	  XFreePixmap(theDisplay, theWindowPtr->pixmap_buffer);
	  theWindowPtr->pixmap_buffer = NULL;
	}
	Iconify(theWindowPtr);
      }
    thePrevExposedWindow=0;
    break;
    
    /************************/
  case ConfigureNotify:
    for(theWindowPtr = theWindowList; theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
      if (theWindowPtr->xwin == theEvent.xmap.window)
      {
	if(theWindowPtr->height != theEvent.xconfigure.height ||
	   theWindowPtr->width  != theEvent.xconfigure.width)
	{
	  theWindowPtr->height = theEvent.xconfigure.height;
	  theWindowPtr->width  = theEvent.xconfigure.width;
	  
	  if(theWindowPtr->pixmap_buffer)
	  {
	    XFreePixmap(theDisplay, theWindowPtr->pixmap_buffer);
	    theWindowPtr->pixmap_buffer = NULL;
	  }
	  Iconic_Before(theWindowPtr);
	}
	break;
      }
    thePrevExposedWindow=0;
    break;
    
    /************************/
  case Expose:
    if(thePrevExposedWindow != theEvent.xexpose.window)
    {
      for(theWindowPtr = theWindowList; doneFlag && theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
      {
	if (theWindowPtr->xwin == theEvent.xexpose.window) 
	{
	  (*(theWindowPtr->paint_function))(theWindowPtr);
	  if(theCrosshairedWindow) SetCrosshairParameters();
	  break;
	}
	for(theButtonPtr = theWindowPtr->button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
	{
	  if(theButtonPtr->xwin == theEvent.xexpose.window)
	  {
	    Paint_Button(theButtonPtr);
	    doneFlag=0;
	    break;
	  }
	}
      }	
      
      for(theButtonPtr = theMainMenu.button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
      {
	if(theButtonPtr->xwin == theEvent.xexpose.window)
	{
	  Paint_Button(theButtonPtr);
	  break;
	}
      }
      
      if(theCrosshairedWindow)
      {
	for(theButtonPtr = theXYCrosshairWindow.button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
	{
	  if(theButtonPtr->xwin == theEvent.xexpose.window)
	  {
	    Paint_Button(theButtonPtr);
	    break;
	  }
	}
      }
      
      if(theOpenDialogBox)             /** Drawing the open dialog box and the associated buttons **/
      {
	if (theOpenDialogBox->xwin == theEvent.xexpose.window)
	  Paint_DialogBox(theOpenDialogBox);
	
	for(j=0; j< theOpenDialogBox->number; j++)
	{
	  if(theOpenDialogBox->button_list[j].xbutton->xwin == theEvent.xexpose.window)
	  {
	    Paint_Button(theOpenDialogBox->button_list[j].xbutton);
	    break;
	  }
	}
      }
      thePrevExposedWindow = theEvent.xexpose.window;
    }
    break;
    
    /************************/
  case ButtonPress:
    if(theCrosshairedWindow && theEvent.xbutton.window == theCrosshairedWindow->xwin)
    {
      UpdateCrosshair(theEvent.xbutton.x, theEvent.xbutton.y);
      break;
    }
    for(theWindowPtr = theWindowList; doneFlag && theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
    {
      for(theButtonPtr = theWindowPtr->button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
      {
	if(theButtonPtr->xwin == theEvent.xbutton.window)
	{
	  button    = theEvent.xbutton.button;
	  theButtonPtr->state = PUSHED_STATE;
	  Paint_Button(theButtonPtr);
	  
	  while(True)
	  {
	    while(XCheckTypedEvent(theDisplay, ButtonPress, &theEvent));
	    XMaskEvent(theDisplay, ButtonReleaseMask, &theEvent);
	    if(theEvent.xbutton.button == button) break;
	  }
	  theButtonPtr->state = NORMAL_STATE;
	  Paint_Button(theButtonPtr);
	  Local_Window_Menu(theWindowPtr, theButtonPtr);
	  doneFlag=0;
	  break;
	}
      }
    }
    for(theButtonPtr = theMainMenu.button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
    {
      if(theButtonPtr->xwin == theEvent.xbutton.window)
      {
	button    = theEvent.xbutton.button;
	theButtonPtr->state = PUSHED_STATE;
	Paint_Button(theButtonPtr);
	
	while(True)
	{
	  while(XCheckTypedEvent(theDisplay, ButtonPress, &theEvent));
	  XMaskEvent(theDisplay, ButtonReleaseMask, &theEvent);
	  if(theEvent.xbutton.button == button) break;
	}
	theButtonPtr->state = NORMAL_STATE;
	Paint_Button(theButtonPtr);
	Main_Menu(theButtonPtr);
	doneFlag=0;
	break;
      }
    }
    if(theOpenDialogBox) 
    {
      for(j=0; j< theOpenDialogBox->number; j++)
      {
	if(theOpenDialogBox->button_list[j].xbutton->xwin == theEvent.xbutton.window)
	{
	  if(theOpenDialogBox->button_list[j].xbutton->state == PUSHED_STATE)
	  {
	    theOpenDialogBox->button_list[j].xbutton->state = NORMAL_STATE;
	    Paint_Button(theOpenDialogBox->button_list[j].xbutton);
	    break;
	  }
	  else if(theOpenDialogBox->button_list[j].xbutton->state == NORMAL_STATE)
	  {
	    for(i=0; i< theOpenDialogBox->number; i++)
	    {
	      if(theOpenDialogBox->button_list[i].xbutton->state == PUSHED_STATE)
	      {
		theOpenDialogBox->button_list[i].xbutton->state = NORMAL_STATE;
		Paint_Button(theOpenDialogBox->button_list[i].xbutton);
		break;
	      }
	    }
	    theOpenDialogBox->button_list[j].xbutton->state = PUSHED_STATE;
	    Paint_Button(theOpenDialogBox->button_list[j].xbutton);
	  }
	  XSetInputFocus(theDisplay, theOpenDialogBox->button_list[j].xbutton->xwin,
			 RevertToParent, CurrentTime);
	  
	  button = theEvent.xbutton.button;
	  while(True)
	  {
	    while(XCheckTypedEvent(theDisplay, ButtonPress, &theEvent));
	    XMaskEvent(theDisplay, ButtonReleaseMask, &theEvent);
	    if(theEvent.xbutton.button == button) break;
	  }
	  DialogBox_Menu(theOpenDialogBox);
	  break;
	}
      }
    }
    thePrevExposedWindow=0;
    break;
    
    /***********************/
  case KeyPress:
    if(theOpenDialogBox)
      for(j=0; j< theOpenDialogBox->number; j++)
      {
	if(theOpenDialogBox->button_list[j].xbutton->state == PUSHED_STATE &&
	   theOpenDialogBox->button_list[j].xbutton->xwin == theEvent.xkey.window)
	  ReadFromKeyborad(&(theEvent.xkey));
      }
    thePrevExposedWindow=0;
    break;
    
    /************************/
  default:
    thePrevExposedWindow=0;
    break;
  }
}

/****************************************************************/

void Refresh_Screen()
{
  WindowType theWindowPtr;
  
  sprintf(theTimeStepButtonPtr->Label, "Time = %g", *theTimeStep);
  Paint_Button(theTimeStepButtonPtr);
  
  for(theWindowPtr = theWindowList; theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
    if(Is_Open(theWindowPtr))  (*(theWindowPtr->paint_function))(theWindowPtr);
}

/****************************************************************/

Paint_Window(theWindow)
WindowType theWindow;
{
  DataType  data_Ptr, ptr;
  LabelType label_Ptr;
  XPoint  *X_Points, Tick_Marks[2];
  XRectangle theClientArea;

  int n, i, j, k1, k2, maxlen, x1, y1, x2, y2; 
  char buffer1[20], buffer2[20];
  float m, b, m1, b1, temp;
  
  data_Ptr = theWindow->data;
  label_Ptr= theWindow->label;

  /****************************/
  /* AutoRescaling the y-axis */
  
  if (Is_Y_AutoRescale(theWindow) && (n= *(theWindow->data->npoints)))
  {
    label_Ptr->Y_Max= label_Ptr->Y_Min= data_Ptr->y[0];
    for(ptr= data_Ptr; ptr != NULL; ptr= ptr->next)
    {
      n= *(ptr->npoints);
      for (i=0; i<n; i++)
      {
	label_Ptr->Y_Max = max(label_Ptr->Y_Max, ptr->y[i]);
	label_Ptr->Y_Min = min(label_Ptr->Y_Min, ptr->y[i]);
      }
    }
    label_Ptr->Y_Max *= label_Ptr->Y_Scale;
    label_Ptr->Y_Min *= label_Ptr->Y_Scale;
    
    if(Is_Y_Log(theWindow))
      label_Ptr->Y_Min = max(label_Ptr->Y_Min, label_Ptr->Y_Max/1e6);
  }
  if(Is_Y_Log(theWindow)) 
  {
    label_Ptr->Y_Max= pow(10.0,  ceil(log10(label_Ptr->Y_Max+DBL_MIN)));
    label_Ptr->Y_Min= pow(10.0, floor(0.01+log10(label_Ptr->Y_Min+DBL_MIN)));
  }

  /***************************/
  /* AutoRescaling the x-axis*/

  if (Is_X_AutoRescale(theWindow) && (n= *(theWindow->data->npoints)))
  {
    label_Ptr->X_Max= label_Ptr->X_Min= data_Ptr->x[0];
    for(ptr= data_Ptr; ptr != NULL; ptr= ptr->next)
    {
      n= *(ptr->npoints);
      for (i=0; i<n; i++)
      {
	label_Ptr->X_Max = max(label_Ptr->X_Max, ptr->x[i]);
	label_Ptr->X_Min = min(label_Ptr->X_Min, ptr->x[i]);
      }
    }
    label_Ptr->X_Max *= label_Ptr->X_Scale;
    label_Ptr->X_Min *= label_Ptr->X_Scale;

    if(Is_X_Log(theWindow))
      label_Ptr->X_Min = max(label_Ptr->X_Min, label_Ptr->X_Max/1e6);
  }
  if(Is_X_Log(theWindow))
  {
    label_Ptr->X_Max= pow(10.0,  ceil(log10(label_Ptr->X_Max+DBL_MIN)));
    label_Ptr->X_Min= pow(10.0, floor(0.01+log10(label_Ptr->X_Min+DBL_MIN)));
  }
  if (label_Ptr->X_Max == label_Ptr->X_Min || label_Ptr->Y_Max == label_Ptr->Y_Min) return(1);
  							/* ddd: just against warnings */
  /*********************************************/
  /* Setting up a Pixmap buffer for the window */

  if(!Was_Open_Before(theWindow))
  {
    theClientArea.x = 0;
    theClientArea.y = theFontHeight+16;
    theClientArea.width = theWindow->width;
    theClientArea.height= theWindow->height;
    XSetClipRectangles(theDisplay, theWindow->xwingc, 0, 0, &theClientArea, 1, Unsorted);
    
    theWindow->pixmap_buffer = XCreatePixmap(theDisplay, theWindow->xwin, 
					     theWindow->width, theWindow->height, theDepth);
  }
  
  /*******************************/
  /* Draw labels and plot border */
  
  if(!Was_Open_Before(theWindow) || Is_Y_AutoRescale(theWindow))
  {
    XSetForeground(theDisplay, theWindow->xwingc, GrayShade[3]);
    XFillRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		   0, 0, theWindow->width, theWindow->height);

    sprintf(buffer1, "%.3G", label_Ptr->Y_Max);
    sprintf(buffer2, "%.3G", label_Ptr->Y_Min);
    
    i = strlen(buffer1);
    j = strlen(buffer2);
    
    k1 = XTextWidth(theFontStruct, buffer1, i);
    k2 = XTextWidth(theFontStruct, buffer2, j);
    maxlen= (k1 > k2) ? k1 : k2;
    
    x1= maxlen+3;
    x2= theWindow->width-3;
    y1= theFontHeight+20;
    y2= theWindow->height-(theFontAscent+theFontDescent+7);
    
    XSetForeground(theDisplay, theWindow->xwingc, theWinTextColor);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		maxlen-k1+1, y1+theFontAscent, buffer1, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		maxlen-k2+1, y2-2, buffer2, j);
    
    /**********************************************************/
    /* Drawing the boundary of the client area and tick marks */
    
    XSetForeground(theDisplay, theWindow->xwingc, theBorderColor);
    XDrawRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x1, y1, x2-x1, y2-y1);

    XSetForeground(theDisplay, theWindow->xwingc, theTickMarkColor);
    if(Is_Y_Log(theWindow))
    {
      temp = log10(DBL_MIN+label_Ptr->Y_Max/(label_Ptr->Y_Min+DBL_MIN));
      for(i=1; i<temp; i++)
      {
	Tick_Marks[0].x= x1-3;
	Tick_Marks[0].y= y1 +i*(y2-y1)/temp;
	Tick_Marks[1].x= x1-1;
	Tick_Marks[1].y= y1 +i*(y2-y1)/temp;
	XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		   Tick_Marks, 2, CoordModeOrigin);
      }
    }
    else if( (label_Ptr->Y_Min < 0.0 && 0.0 < label_Ptr->Y_Max) ||
	    (label_Ptr->Y_Max < 0.0 && 0.0 < label_Ptr->Y_Min))
    {
      Tick_Marks[0].x= x1-3;
      Tick_Marks[0].y= y1 +label_Ptr->Y_Max*(y2-y1)/(label_Ptr->Y_Max -label_Ptr->Y_Min);
      Tick_Marks[1].x= x1-1;
      Tick_Marks[1].y= y1 +label_Ptr->Y_Max*(y2-y1)/(label_Ptr->Y_Max -label_Ptr->Y_Min);
      XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		 Tick_Marks, 2, CoordModeOrigin);
    }
    theWindow->ulxc = x1;
    theWindow->ulyc = y1;
    theWindow->lrxc = x2;
    theWindow->lryc = y2;
  }
  x1 = theWindow->ulxc+1;
  y1 = theWindow->ulyc+1;
  x2 = theWindow->lrxc-1;
  y2 = theWindow->lryc-1;
  
  if (!Was_Open_Before(theWindow) || Is_X_AutoRescale(theWindow) || Is_Y_AutoRescale(theWindow))
  {
    XSetForeground(theDisplay, theWindow->xwingc, theTickMarkColor);
    if(Is_X_Log(theWindow))
    {
      temp = log10(DBL_MIN+label_Ptr->X_Max/(label_Ptr->X_Min+DBL_MIN));
      for(i=1; i<temp; i++)
      {
	Tick_Marks[0].x= x1 +i*(x2-x1)/temp;
	Tick_Marks[0].y= y2+3;
	Tick_Marks[1].x= x1 +i*(x2-x1)/temp;
	Tick_Marks[1].y= y2+5;
	XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		   Tick_Marks, 2, CoordModeOrigin);
      }
    }
    else if( (label_Ptr->X_Min < 0.0 && 0.0 < label_Ptr->X_Max) ||
	    (label_Ptr->X_Max < 0.0 && 0.0 < label_Ptr->X_Min))
    {
      Tick_Marks[0].x= x2 -label_Ptr->X_Max*(x2-x1)/(label_Ptr->X_Max -label_Ptr->X_Min);
      Tick_Marks[0].y= y2+3;
      Tick_Marks[1].x= x2 -label_Ptr->X_Max*(x2-x1)/(label_Ptr->X_Max -label_Ptr->X_Min);
      Tick_Marks[1].y= y2+5;
      XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		 Tick_Marks, 2, CoordModeOrigin);
    }
    XSetForeground(theDisplay, theWindow->xwingc, GrayShade[3]);
    XFillRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		   0, y2+6, x2, theWindow->height);
    
    sprintf(buffer1, "%g", label_Ptr->X_Max);
    sprintf(buffer2, "%g", label_Ptr->X_Min);
    
    i = strlen(buffer1);
    j = strlen(buffer2);
    
    maxlen= XTextWidth(theFontStruct, buffer1, i);
    
    XSetForeground(theDisplay, theWindow->xwingc, theWinTextColor);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x2-maxlen-1,
		y2+theFontAscent+6, buffer1, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x1, 
		y2+theFontAscent+6, buffer2, j);
    
    i = strlen(label_Ptr->X_Label);
    maxlen= XTextWidth(theFontStruct, label_Ptr->X_Label, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, (x1+x2-maxlen)/2, 
		y2+theFontAscent+6, label_Ptr->X_Label, i);
  }
  
  if (!Was_Open_Before(theWindow) || Is_X_AutoRescale(theWindow) ||
      Is_Y_AutoRescale(theWindow) || !Is_Trace_On(theWindow))
  {
    XSetForeground(theDisplay, theWindow->xwingc, theBKGDColor);
    XFillRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x1, y1, x2-x1, y2-y1+1);
    Open_Before(theWindow);
  }
  
  /*******************************************/
  /* Plotting the graph(es) into the window. */
  
  theClientArea.x = x1;
  theClientArea.y = y1;
  theClientArea.width = x2-x1;
  theClientArea.height= y2-y1+1;
  XSetClipRectangles(theDisplay, theWindow->xwingc, 0, 0, &theClientArea, 1, Unsorted);
  
  if(Is_Y_Log(theWindow))
  {
    m = (y1-y2)/log10(DBL_MIN+label_Ptr->Y_Max/(label_Ptr->Y_Min+DBL_MIN));
    b = (log10(label_Ptr->Y_Max)*y2 -log10(label_Ptr->Y_Min)*y1)/log10(label_Ptr->Y_Max/label_Ptr->Y_Min) +0.5;
  }
  else
  {
    m = (y1-y2)/(label_Ptr->Y_Max -label_Ptr->Y_Min +DBL_MIN)*label_Ptr->Y_Scale;
    b = (label_Ptr->Y_Max*y2 - label_Ptr->Y_Min*y1)/(label_Ptr->Y_Max - label_Ptr->Y_Min +DBL_MIN) +0.5;
  }
  if(Is_X_Log(theWindow))
  {
    m1= (x2-x1)/log10(label_Ptr->X_Max/label_Ptr->X_Min);
    b1= (log10(label_Ptr->X_Max)*x1 -log10(label_Ptr->X_Min)*x2)/log10(label_Ptr->X_Max/label_Ptr->X_Min) +0.5;
  }
  else
  {
    m1= (x2-x1)/(label_Ptr->X_Max -label_Ptr->X_Min +DBL_MIN)*label_Ptr->X_Scale;
    b1= (label_Ptr->X_Max*x1 - label_Ptr->X_Min*x2)/(label_Ptr->X_Max - label_Ptr->X_Min +DBL_MIN) +0.5;
  }
  for(ptr= data_Ptr; ptr != NULL; ptr= ptr->next)
  {
    XSetForeground(theDisplay, theWindow->xwingc, ptr->color);
    n = *(ptr->npoints);
    
    if (!(X_Points= (XPoint *)malloc(n*sizeof(XPoint)))) putchar(7);
    
    if(Is_X_Log(theWindow)) 
      for (i=0; i<n; i++) X_Points[i].x= m1*log10(fabs(label_Ptr->X_Scale*ptr->x[i])+DBL_MIN)+b1;
    else for (i=0; i<n; i++) X_Points[i].x= m1*ptr->x[i]+b1;
    
    if(Is_Y_Log(theWindow)) 
      for (i=0; i<n; i++) X_Points[i].y= m*log10(fabs(label_Ptr->Y_Scale*ptr->y[i])+DBL_MIN)+b;
    else for (i=0; i<n; i++) X_Points[i].y= m*ptr->y[i]+b;
    
    if (Is_Scatter(ptr))
      XDrawPoints(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, X_Points, n, CoordModeOrigin);
    else
      XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, X_Points, n, CoordModeOrigin);
    
    free(X_Points);
  }
  /**************************************************************/

  theClientArea.x = 0;
  theClientArea.y = theFontHeight+16;
  theClientArea.width = theWindow->width;
  theClientArea.height= theWindow->height;
  XSetClipRectangles(theDisplay, theWindow->xwingc, 0, 0, &theClientArea, 1, Unsorted);

  XCopyArea(theDisplay, theWindow->pixmap_buffer, theWindow->xwin, theWindow->xwingc, 0, 0, 
	    theWindow->width, theWindow->height, 0, 0);

    return(1);             /* ddd: just against warnings */
}

/****************************************************************/

#define  BACK         0
#define  FRONT        1

#define  ABOVE        0
#define  UPPER        1
#define  LOWER        2

#define  FIRST_QUAD   0
#define  SECOND_QUAD  1
#define  THIRD_QUAD   2
#define  FOURTH_QUAD  3

/****************************************************************/

Paint_ThreeD_Window(theWindow)
WindowType theWindow;
{
  DataType   data_Ptr;
  LabelType  label_Ptr;
  MeshType **theMeshPoint, theBox[8];
  StringType theString[8];
  XPoint     thePolygon[5];

  float n1, n2, n3, v1, v2, v3;
  float u1, u2, u3, up1, up2, up3;
  float a1, a2, a3, b1, b2, b3;
  float xprojmax, xprojmin;
  float yprojmax, yprojmin; 
  float mag, c1, c2, d1, d2;
  float xtemp, ytemp, ztemp;

  int   m, mstart, mend, n, nend, nstart;
  int   i, j, k, x1, y1, x2, y2, colornumber;
  int   phi_flag, theta_flag, i1, j1, k1, maxlen;
  int   xstart, xend, xstep, ystart, yend, ystep;

  data_Ptr = theWindow->data;
  label_Ptr= theWindow->label;
  if(!Is_Scatter(data_Ptr)) m= *(data_Ptr->mpoints); 
  n= *(data_Ptr->npoints);

  /****************************/
  /* AutoRescaling the x-axis */

  if(Is_X_AutoRescale(theWindow))
  {
    if(Is_Scatter(data_Ptr))
    {
      if(n)
      {
	label_Ptr->X_Max= label_Ptr->X_Min= data_Ptr->x[0];
	for (i=1; i<n; i++)
	{
	  label_Ptr->X_Max = max(label_Ptr->X_Max, data_Ptr->x[i]);
	  label_Ptr->X_Min = min(label_Ptr->X_Min, data_Ptr->x[i]);
	}
      }
    }
    else if(m)
    {
      label_Ptr->X_Max= data_Ptr->x[m-1];
      label_Ptr->X_Min= data_Ptr->x[0];
    }
    label_Ptr->X_Max*= label_Ptr->X_Scale;
    label_Ptr->X_Min*= label_Ptr->X_Scale;
    if(Is_X_Log(theWindow)) label_Ptr->X_Min = max(label_Ptr->X_Min, label_Ptr->X_Max/1e6);
  }
  if(Is_X_Log(theWindow))
  {
    label_Ptr->X_Max= pow(10.0,  ceil(log10(label_Ptr->X_Max+DBL_MIN)));
    label_Ptr->X_Min= pow(10.0, floor(0.01+log10(label_Ptr->X_Min+DBL_MIN)));
  }
  if(!Is_Scatter(data_Ptr))
  {
    mstart = m*(label_Ptr->X_Min/label_Ptr->X_Scale - data_Ptr->x[0])/(data_Ptr->x[m-1] -data_Ptr->x[0])+.5;
    if(mstart <0) mstart=0;  else if(mstart >m) mstart=m;
    mend   = m*(label_Ptr->X_Max/label_Ptr->X_Scale - data_Ptr->x[0])/(data_Ptr->x[m-1] -data_Ptr->x[0]);
    if(mend <0)   mend=0;    else if(mend >m) mend=m;
  }  
  /****************************/
  /* AutoRescaling the y-axis */

  if (Is_Y_AutoRescale(theWindow) && n)
  {
    if(Is_Scatter(data_Ptr))
    {
      label_Ptr->Y_Max = label_Ptr->Y_Min = data_Ptr->y[0];
      for (i=1; i<n; i++)
      {
	label_Ptr->Y_Max = max(label_Ptr->Y_Max, data_Ptr->y[i]);
	label_Ptr->Y_Min = min(label_Ptr->Y_Min, data_Ptr->y[i]);
      }
    }
    else
    {
      label_Ptr->Y_Max= data_Ptr->y[n-1];
      label_Ptr->Y_Min= data_Ptr->y[0];
    }
    label_Ptr->Y_Max *= label_Ptr->Y_Scale;
    label_Ptr->Y_Min *= label_Ptr->Y_Scale;
    if(Is_Y_Log(theWindow)) label_Ptr->Y_Min = max(label_Ptr->Y_Min, label_Ptr->Y_Max/1e6);
  }
  if(Is_Y_Log(theWindow))
    {
    label_Ptr->Y_Max= pow(10.0,  ceil(log10(label_Ptr->Y_Max+DBL_MIN)));
    label_Ptr->Y_Min= pow(10.0, floor(0.01+log10(label_Ptr->Y_Min+DBL_MIN)));
  }
  if(!Is_Scatter(data_Ptr))
  {
    nstart = n*(label_Ptr->Y_Min/label_Ptr->Y_Scale - data_Ptr->y[0])/(data_Ptr->y[n-1] -data_Ptr->y[0])+.5;
    if(nstart <0) nstart=0;  else if(nstart >n) nstart=n;
    nend   = n*(label_Ptr->Y_Max/label_Ptr->Y_Scale - data_Ptr->y[0])/(data_Ptr->y[n-1] -data_Ptr->y[0]);
    if(nend <0)   nend=0;    else if(nend >n) nend=n;
  }
  /****************************/
  /* AutoRescaling the z-axis */

  if (Is_Z_AutoRescale(theWindow) && (n || m))
  {
    if(Is_Scatter(data_Ptr))
    {
      label_Ptr->Z_Max= label_Ptr->Z_Min= data_Ptr->zscat[0];
      for (i=1; i<n; i++)
      {
	label_Ptr->Z_Max = max(label_Ptr->Z_Max, data_Ptr->zscat[i]);
	label_Ptr->Z_Min = min(label_Ptr->Z_Min, data_Ptr->zscat[i]);
      }
    }
    else
    {
      label_Ptr->Z_Max= label_Ptr->Z_Min= data_Ptr->z[mstart][nstart];
      for (i=mstart; i<mend; i++)
	for (j=nstart; j<nend; j++)
	{
	  label_Ptr->Z_Max = max(label_Ptr->Z_Max, data_Ptr->z[i][j]);
	  label_Ptr->Z_Min = min(label_Ptr->Z_Min, data_Ptr->z[i][j]);
	}
    }
    label_Ptr->Z_Max *= label_Ptr->Z_Scale;
    label_Ptr->Z_Min *= label_Ptr->Z_Scale;
    if(Is_Z_Log(theWindow)) label_Ptr->Z_Min = max(label_Ptr->Z_Min, label_Ptr->Z_Max/1e6);
  }
  if(Is_Z_Log(theWindow))
  {
    label_Ptr->Z_Max= pow(10.0,  ceil(log10(label_Ptr->Z_Max+DBL_MIN)));
    label_Ptr->Z_Min= pow(10.0, floor(0.01+log10(label_Ptr->Z_Min+DBL_MIN)));
  }
  
  if (label_Ptr->Z_Max == label_Ptr->Z_Min || label_Ptr->Y_Max == label_Ptr->Y_Min ||
      label_Ptr->X_Max == label_Ptr->X_Min) return(1);
  				/* ddd: just against warnings */
  /*********************************************/
  /* Setting up a Pixmap buffer for the window */
  
  if(!Was_Open_Before(theWindow))
  {
    theWindow->pixmap_buffer = XCreatePixmap(theDisplay, theWindow->xwin, 
					     theWindow->width, theWindow->height, theDepth);
    Open_Before(theWindow);
  }
  
  /*******************************************************************/
  
  XSetForeground(theDisplay, theWindow->xwingc, GrayShade[3]);
  XFillRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		 0, 0, theWindow->width, theWindow->height);
  
  /******************************************************/ 
  /* Determining the octant where the viewer is located */

  theWindow->theta= fmod(180.+theWindow->theta, 180.);
  theWindow->phi  = fmod(360.+theWindow->phi, 360.);
  
  if(0 <= theWindow->phi && theWindow->phi <= 90)        phi_flag = FIRST_QUAD;
  else if(90 < theWindow->phi && theWindow->phi <= 180)  phi_flag = SECOND_QUAD;
  else if(180 < theWindow->phi && theWindow->phi <= 270) phi_flag = THIRD_QUAD;
  else if(270 < theWindow->phi && theWindow->phi <= 360) phi_flag = FOURTH_QUAD;
  
  if(theWindow->theta == 0.0)                             theta_flag = ABOVE;
  else if(0 < theWindow->theta && theWindow->theta <= 90) theta_flag = UPPER;
  else                                                    theta_flag = LOWER;
  
  /************************************/ 
  /* Calculating the rotation vectors */

  n1= sin(theWindow->theta*M_PI/180.)*cos(theWindow->phi*M_PI/180.);
  n2= sin(theWindow->theta*M_PI/180.)*sin(theWindow->phi*M_PI/180.);
  n3= cos(theWindow->theta*M_PI/180.);
  
  if(theta_flag == ABOVE)
  {
    up1= 0;  up2= 1;  up3= 0;
  }
  else
  {
    up1= 0;  up2= 0;  up3= 1;
  }
  
  u1  = up2*n3 -up3*n2;
  u2  = up3*n1 -up1*n3;
  u3  = up1*n2 -up2*n1;
  mag = sqrt(u1*u1 + u2*u2 + u3*u3);
  
  u1 /= mag;
  u2 /= mag;
  u3 /= mag;
  
  v1  = n2*u3 -n3*u2;
  v2  = n3*u1 -n1*u3;
  v3  = n1*u2 -n2*u1;
  
  /***********************************************************/
  /* Calculating the bounding box and the projection scaling */
  
  theBox[0].x = 0;       theBox[1].x = u1;  theBox[2].x = u1 +u2;  theBox[3].x = u2;
  theBox[0].y = 0;       theBox[1].y = v1;  theBox[2].y = v1 +v2;  theBox[3].y = v2;
  
  theBox[4].x = u2 +u3;  theBox[5].x = u3;  theBox[6].x = u1 +u3;  theBox[7].x = u1 +u2 +u3;
  theBox[4].y = v2 +v3;  theBox[5].y = v3;  theBox[6].y = v1 +v3;  theBox[7].y = v1 +v2 +v3;
  
  xprojmin = xprojmax = theBox[0].x;
  yprojmin = yprojmax = theBox[0].y;
  for(i = 1; i < 8; i++)
  {
    xprojmin = (xprojmin < theBox[i].x) ? xprojmin : theBox[i].x;
    xprojmax = (xprojmax > theBox[i].x) ? xprojmax : theBox[i].x;
    yprojmin = (yprojmin < theBox[i].y) ? yprojmin : theBox[i].y;
    yprojmax = (yprojmax > theBox[i].y) ? yprojmax : theBox[i].y;
  }
  
  /********************************************************************/
  /* selecting the labels to print based on the given point of view   */

  if(theta_flag == ABOVE)
  {
    sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Max);
    sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label);
    sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Min);
    sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Min);
    sprintf(theString[4].buffer, "%s", label_Ptr->X_Label);
    sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Max);
  }
  else
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Min); theString[0].x = u1;       theString[0].y = v1;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = u1+.5*u2; theString[1].y = v1+.5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Max); theString[2].x = u1+u2;    theString[2].y = v1+v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Max); theString[3].x = u1+u2;    theString[3].y = v1+v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1+u2; theString[4].y = .5*v1+v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Min); theString[5].x = u2;       theString[5].y = v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u2;       theString[6].y = v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u2+u3;    theString[7].y = v2+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Max); theString[0].x = u1;       theString[0].y = v1;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1;    theString[1].y = .5*v1;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Min); theString[2].x = 0.0;      theString[2].y = 0.0;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Min); theString[3].x = 0.0;      theString[3].y = 0.0;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = .5*u2;    theString[4].y = .5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Max); theString[5].x = u2;       theString[5].y = v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u2;       theString[6].y = v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u2+u3;    theString[7].y = v2+v3;
	}
	break;
	
      case SECOND_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Max); theString[0].x = u1+u2;    theString[0].y = v1+v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1+u2; theString[1].y = .5*v1+v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Min); theString[2].x = u2;       theString[2].y = v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Max); theString[3].x = u2;       theString[3].y = v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = .5*u2;    theString[4].y = .5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Min); theString[5].x = 0.0;      theString[5].y = 0.0;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = 0.0;      theString[6].y = 0.0;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u3;       theString[7].y = v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Max); theString[0].x = u1+ u2;   theString[0].y = v1+v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = u1+.5*u2; theString[1].y = v1+.5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Min); theString[2].x = u1;       theString[2].y = v1;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Max); theString[3].x = u1;       theString[3].y = v1;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1;    theString[4].y = .5*v1;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Min); theString[5].x = 0.0;      theString[5].y = 0.0;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = 0.0;      theString[6].y = 0.0;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u3;       theString[7].y = v3;
	}
	break;
	
      case THIRD_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Max); theString[0].x = u2;       theString[0].y = v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = .5*u2;    theString[1].y = .5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Min); theString[2].x = 0.0;      theString[2].y = 0.0;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Min); theString[3].x = 0.0;      theString[3].y = 0.0;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1;    theString[4].y = .5*v1;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Max); theString[5].x = u1;       theString[5].y = v1;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1;       theString[6].y = v1;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u3;    theString[7].y = v1+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Min); theString[0].x = u2;       theString[0].y = v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1+u2; theString[1].y = .5*v1+v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Max); theString[2].x = u1+u2;    theString[2].y = v1+v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Max); theString[3].x = u1+u2;    theString[3].y = v1+v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = u1+.5*u2; theString[4].y = v1+.5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Min); theString[5].x = u1;       theString[5].y = v1;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1;       theString[6].y = v1;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u3;    theString[7].y = v1+v3;
	}
	break;
	
      case FOURTH_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Min); theString[0].x = 0.0;      theString[0].y = 0.0;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1;    theString[1].y = .5*v1;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Max); theString[2].x = u1;       theString[2].y = v1;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Min); theString[3].x = u1;       theString[3].y = v1;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = u1+.5*u2; theString[4].y = v1+.5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Max); theString[5].x = u1+u2;    theString[5].y = v1+v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1+u2;    theString[6].y = v1+v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u2+u3; theString[7].y = v1+v2+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Min); theString[0].x = 0.0;      theString[0].y = 0.0;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = .5*u2;    theString[1].y = .5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Max); theString[2].x = u2;       theString[2].y = v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Min); theString[3].x = u2;       theString[3].y = v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1+u2; theString[4].y = .5*v1+v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Max); theString[5].x = u1+u2;    theString[5].y = v1+v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1+u2;    theString[6].y = v1+v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u2+u3; theString[7].y = v1+v2+v3;
	}
	break;
      }
  }

  /*******************************/
  /* painting the color spectra  */

  y1 = theFontHeight+16+2;
  y2 = theWindow->height-theFontHeight-4;
  
  if(Is_ColorCode_On(theWindow))
  {
    for(i=0; i <2*MAXTHREEDCOLORS; i+=2)
    {
      XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[i/2]);
      thePolygon[0].x = theWindow->ulxc+i;    thePolygon[0].y = 0;
      thePolygon[1].x = theWindow->ulxc+i;    thePolygon[1].y = theWindow->ulyc;
      XDrawLines(theDisplay, theWindow->pixmap_buffer,
		 theWindow->xwingc, thePolygon, 2, CoordModeOrigin);
      
      thePolygon[0].x = theWindow->ulxc+i+1;  thePolygon[0].y = 0;
      thePolygon[1].x = theWindow->ulxc+i+1;  thePolygon[1].y = theWindow->ulyc;
      XDrawLines(theDisplay, theWindow->pixmap_buffer,
		 theWindow->xwingc, thePolygon, 2, CoordModeOrigin);
    }
    XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[0]);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		theWindow->ulxc, theWindow->ulyc+theFontAscent+2, "L", 1);
    
    XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[MAXTHREEDCOLORS-1]);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		theWindow->ulxc+2*MAXTHREEDCOLORS -XTextWidth(theFontStruct, "H", 1),
		theWindow->ulyc+theFontAscent+2, "H", 1);
    y1+= theFontHeight+2;
  }
  /***************************************/
  /* painting the labels                 */
  
  x1 = 2;
  x2 = theWindow->width-2;
  
  c2 = (y1-y2)/(yprojmax -yprojmin +DBL_MIN);
  d2 = (yprojmax*y2 - yprojmin*y1)/(yprojmax - yprojmin + DBL_MIN) + 0.5;
  
  XSetForeground(theDisplay, theWindow->xwingc, theWinTextColor);
  
  if(theta_flag == ABOVE)
  {
    i = strlen(theString[0].buffer); i1= XTextWidth(theFontStruct, theString[0].buffer, i);
    j = strlen(theString[1].buffer); j1= XTextWidth(theFontStruct, theString[1].buffer, j);
    k = strlen(theString[2].buffer); k1= XTextWidth(theFontStruct, theString[2].buffer, k);
    maxlen = (i1 > j1) ? i1 : j1;
    maxlen = (k1 > maxlen) ? k1 : maxlen;

    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x1+maxlen-i1, y1+theFontAscent, theString[0].buffer, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x1+(maxlen-j1)/2, (y1+y2)/2, theString[1].buffer, j);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x1+maxlen-k1, y2-theFontDescent, theString[2].buffer, k);
    x1 += maxlen+2;

    i = strlen(theString[3].buffer);
    j = strlen(theString[4].buffer);
    k = strlen(theString[5].buffer); k1= XTextWidth(theFontStruct, theString[5].buffer, k);

    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x1, y2+theFontAscent+2, theString[3].buffer, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		(x1+x2)/2, y2+theFontAscent+2, theString[4].buffer, j);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x2-k1-1, y2+theFontAscent+2, theString[5].buffer, k);

    c1 = (x2-x1)/(xprojmax -xprojmin +DBL_MIN);
    d1 = (xprojmax*x1 - xprojmin*x2)/(xprojmax - xprojmin + DBL_MIN) + 0.5;
    
    if(Is_Scatter(data_Ptr))
    {
      XSetForeground(theDisplay, theWindow->xwingc, theBKGDColor);
      XFillRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x1, y1, x2-x1, y2-y1+1);
      XSetForeground(theDisplay, theWindow->xwingc, theWhitePixel);
      XDrawRectangle(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, x1, y1, x2-x1, y2-y1);
    }
  }
  else
  {
    i = strlen(theString[0].buffer);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x1, (int)(c2*theString[0].y+d2+theFontAscent), theString[0].buffer, i);  
    x1 += XTextWidth(theFontStruct, theString[0].buffer, i) +2;
    
    i = strlen(theString[5].buffer); i1= XTextWidth(theFontStruct, theString[5].buffer, i);
    j = strlen(theString[6].buffer); j1= XTextWidth(theFontStruct, theString[6].buffer, j);
    k = strlen(theString[7].buffer); k1= XTextWidth(theFontStruct, theString[7].buffer, k);
    
    maxlen = (i1 > j1) ? i1 : j1;
    maxlen = (k1 > maxlen) ? k1 : maxlen;
    x2 -= maxlen;
    
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x2, (int)(c2*theString[5].y+d2+theFontAscent+5), theString[5].buffer, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x2+maxlen-j1, (int)(c2*theString[6].y+d2-theFontDescent-2), theString[6].buffer, j);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		x2+maxlen-k1, (int)(c2*theString[7].y+d2+theFontAscent), theString[7].buffer, k);
    x2 -= 2;
    
    c1 = (x2-x1)/(xprojmax -xprojmin +DBL_MIN);
    d1 = (xprojmax*x1 - xprojmin*x2)/(xprojmax - xprojmin + DBL_MIN) + 0.5;
    
    i = strlen(theString[2].buffer);
    i1= XTextWidth(theFontStruct, theString[2].buffer, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		(int)(c1*theString[2].x+d1-i1-5), y2+theFontAscent+2, theString[2].buffer, i);
    
    j = strlen(theString[3].buffer);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		(int)(c1*theString[3].x+d1+5), y2+theFontAscent+2, theString[3].buffer, j);
    
    i = strlen(theString[1].buffer);
    i1= XTextWidth(theFontStruct, theString[1].buffer, i);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		(int)(c1*theString[1].x+d1-i1-5), (int)(c2*theString[1].y+d2+theFontAscent), theString[1].buffer, i);
    
    j = strlen(theString[4].buffer);
    XDrawString(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		(int)(c1*theString[4].x+d1+5), (int)(c2*theString[4].y+d2+theFontAscent+5), theString[4].buffer, j);
  }
  /***********************/
  /* Draw the back walls */

  if(theta_flag != ABOVE)
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, BACK);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 1, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 4, BACK);
	break;
	
      case SECOND_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, BACK);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 1, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 2, BACK);
	break;
	
      case THIRD_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, BACK);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 2, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 3, BACK);
	break;
	
      case FOURTH_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, BACK);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 3, BACK);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 4, BACK);
	break;
      }
  }
  
  /***********************************************/
  /* Used for scaling the arrays before rotating */

  if(Is_X_Log(theWindow))
  {
    a1 = 1.0/log10(label_Ptr->X_Max/label_Ptr->X_Min);
    b1 = log10(label_Ptr->X_Min/label_Ptr->X_Scale)/log10(label_Ptr->X_Max/label_Ptr->X_Min);
  }
  else
  {
    a1 = label_Ptr->X_Scale/(label_Ptr->X_Max - label_Ptr->X_Min);
    b1 = label_Ptr->X_Min/(label_Ptr->X_Max - label_Ptr->X_Min);
  }
  if(Is_Y_Log(theWindow))
  {
    a2 = 1.0/log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
    b2 = log10(label_Ptr->Y_Min/label_Ptr->Y_Scale)/log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
  }
  else
  {
    a2 = label_Ptr->Y_Scale/(label_Ptr->Y_Max - label_Ptr->Y_Min);
    b2 = label_Ptr->Y_Min/(label_Ptr->Y_Max - label_Ptr->Y_Min); 
  }
  if(Is_Z_Log(theWindow))
  {
    a3 = 1.0/log10(label_Ptr->Z_Max/label_Ptr->Z_Min);
    b3 = log10(label_Ptr->Z_Min/label_Ptr->Z_Scale)/log10(label_Ptr->Z_Max/label_Ptr->Z_Min);
  }
  else
  {
    a3 = label_Ptr->Z_Scale/(label_Ptr->Z_Max - label_Ptr->Z_Min);
    b3 = label_Ptr->Z_Min/(label_Ptr->Z_Max - label_Ptr->Z_Min);
  }  
  /********************************************/
  /* do the actual 3d drawing onto the pixmap */
  
  if(Is_Scatter(data_Ptr))
  { 
    XSetForeground(theDisplay, theWindow->xwingc, data_Ptr->color);
    for(i = 0; i< n; i++)
    { 
      if(Is_X_Log(theWindow)) xtemp = a1*log10(fabs(data_Ptr->x[i]))-b1;
      else                    xtemp = a1*data_Ptr->x[i] -b1;
      if(Is_Y_Log(theWindow)) ytemp = a2*log10(fabs(data_Ptr->y[i]))-b2;
      else                    ytemp = a2*data_Ptr->y[i] -b2;
      if(Is_Z_Log(theWindow)) ztemp = a3*log10(fabs(data_Ptr->zscat[i])) -b3;
      else                    ztemp = a3*data_Ptr->zscat[i] -b3;
      if(0.0<xtemp && xtemp<1.0 && 0.0<ytemp && ytemp<1.0 && 0.0<ztemp && ztemp<1.0)
      {
	if(Is_ColorCode_On(theWindow))
	{
	  if(Is_Z_Log(theWindow)) 
	    colornumber = MAXTHREEDCOLORS*(a3*log10(fabs(data_Ptr->zscat[i])) -b3);
	  else
	    colornumber = MAXTHREEDCOLORS*(a3*(data_Ptr->zscat[i]) -b3);
	  if(colornumber >= MAXTHREEDCOLORS) colornumber = MAXTHREEDCOLORS-1;
	  else if(colornumber < 0) colornumber = 0;
	  XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[colornumber]);
	}
	XDrawPoint(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc,
		   (int)(c1*(u1*xtemp +u2*ytemp +u3*ztemp) +d1),
		   (int)(c2*(v1*xtemp +v2*ytemp +v3*ztemp) +d2));
      }
    }
  }
  else
  {
    theMeshPoint = (MeshType **)malloc(m*sizeof(MeshType *));
    for(i = 0; i < m; i++)
    {
      theMeshPoint[i] = (MeshType *)malloc(n*sizeof(MeshType));
      for(j = 0; j < n; j++)
      {
	if(Is_X_Log(theWindow)) xtemp = a1*log10(fabs(data_Ptr->x[i]))-b1;
	else                    xtemp = a1*data_Ptr->x[i] -b1;
	if(Is_Y_Log(theWindow)) ytemp = a2*log10(fabs(data_Ptr->y[j]))-b2;
	else                    ytemp = a2*data_Ptr->y[j] -b2;
	if(Is_Z_Log(theWindow)) ztemp = a3*log10(fabs(data_Ptr->z[i][j])) -b3;
	else                    ztemp = a3*data_Ptr->z[i][j] -b3;
	if(ztemp >1.0) ztemp = 1.0; else if(ztemp<0.0) ztemp = 0.0;
	theMeshPoint[i][j].x = u1*xtemp +u2*ytemp +u3*ztemp;
	theMeshPoint[i][j].y = v1*xtemp +v2*ytemp +v3*ztemp;
      }
    }
    /*********************************/
    
    switch (phi_flag)
      {
      case FIRST_QUAD:
	xstart = mstart; xend= mend-1; xstep = 1; ystart = nstart; yend= nend-1; ystep = 1;
	break;
	
      case SECOND_QUAD:
	xstart = mend-2; xend= mstart-1; xstep = -1; ystart = nstart; yend= nend-1; ystep = 1;
	break;
	
      case THIRD_QUAD:
	xstart = mend-2; xend= mstart-1; xstep = -1; ystart = nend-2; yend= nstart-1; ystep = -1;
	break;
	
      case FOURTH_QUAD:
	xstart = mstart; xend= mend-1; xstep = 1; ystart = nend-2; yend= nstart-1; ystep = -1;
	break;
      }
    
    for(i = xstart; i != xend; i +=xstep)
      for(j = ystart; j != yend; j +=ystep)
      {
	thePolygon[0].x = thePolygon[4].x = c1*theMeshPoint[i][j].x +d1;
	thePolygon[0].y = thePolygon[4].y = c2*theMeshPoint[i][j].y +d2;
	
	thePolygon[1].x = c1*theMeshPoint[i+1][j].x +d1;
	thePolygon[1].y = c2*theMeshPoint[i+1][j].y +d2;
	
	thePolygon[2].x = c1*theMeshPoint[i+1][j+1].x +d1;
	thePolygon[2].y = c2*theMeshPoint[i+1][j+1].y +d2;
	
	thePolygon[3].x = c1*theMeshPoint[i][j+1].x +d1;
	thePolygon[3].y = c2*theMeshPoint[i][j+1].y +d2;
	
	if(Is_Shading_On(theWindow))
	{      
	  if(Is_ColorCode_On(theWindow))
	  {
	    if(Is_Z_Log(theWindow)) 
	      colornumber = MAXTHREEDCOLORS*(.25*a3*log10(fabs(data_Ptr->z[i][j]*data_Ptr->z[i+1][j]
							  *data_Ptr->z[i+1][j+1]*data_Ptr->z[i][j+1])) -b3);
	    else
	      colornumber = MAXTHREEDCOLORS*(.25*a3*(data_Ptr->z[i][j] +data_Ptr->z[i+1][j] 
						     +data_Ptr->z[i+1][j+1]+data_Ptr->z[i][j+1]) -b3);
	    if(colornumber >= MAXTHREEDCOLORS) colornumber = MAXTHREEDCOLORS-1;
	    else if(colornumber < 0) colornumber = 0;
	    XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[colornumber]);
	  }
	  else
	    XSetForeground(theDisplay, theWindow->xwingc, data_Ptr->color);
	}
	else 
	  XSetForeground(theDisplay, theWindow->xwingc, theBlackPixel);
	
	XFillPolygon(theDisplay, theWindow->pixmap_buffer,
		     theWindow->xwingc, thePolygon, 5, Complex, CoordModeOrigin);
	
	if(Is_Shading_On(theWindow))
	  XSetForeground(theDisplay, theWindow->xwingc, theBlackPixel);
	else 
	{
	  if(Is_ColorCode_On(theWindow))
	  {
	    if(Is_Z_Log(theWindow)) 
	      colornumber = MAXTHREEDCOLORS*(.25*a3*log10(fabs(data_Ptr->z[i][j]*data_Ptr->z[i+1][j]
							  *data_Ptr->z[i+1][j+1]*data_Ptr->z[i][j+1])) -b3);
	    else
	      colornumber = MAXTHREEDCOLORS*(.25*a3*(data_Ptr->z[i][j] +data_Ptr->z[i+1][j] 
						     +data_Ptr->z[i+1][j+1]+data_Ptr->z[i][j+1]) -b3);
	    if(colornumber >= MAXTHREEDCOLORS) colornumber = MAXTHREEDCOLORS-1;
	    else if(colornumber < 0) colornumber = 0;
	    XSetForeground(theDisplay, theWindow->xwingc, ThreeDColor[colornumber]);
	  }
	  else
	    XSetForeground(theDisplay, theWindow->xwingc, data_Ptr->color);
	}
	if(Is_Grid_On(theWindow))
	  XDrawLines(theDisplay, theWindow->pixmap_buffer,
		     theWindow->xwingc, thePolygon, 5, CoordModeOrigin);
      }
    /*********************************************************/
    /* Free up the memory for the memory for the mesh points */
    
    for(i = 0; i < m; i++) free(theMeshPoint[i]);
    free(theMeshPoint);
  }
  
  /***********************/
  /* Draw the front walls */

  if(theta_flag != ABOVE)
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, FRONT);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 2, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 3, FRONT);
	break;
	
      case SECOND_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, FRONT);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 3, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 4, FRONT);
	break;
	
      case THIRD_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, FRONT);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 1, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 4, FRONT);
	break;
	
      case FOURTH_QUAD:
	if(theta_flag == UPPER)
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 5, FRONT);
	else
	  DrawWall(theWindow, theBox, c1, d1, c2, d2, 0, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 1, FRONT);
	DrawWall(theWindow, theBox, c1, d1, c2, d2, 2, FRONT);
	break;
      }
  }
    
  /***************************************************************************************/
  XCopyArea(theDisplay, theWindow->pixmap_buffer, theWindow->xwin,
	    theWindow->xwingc, 0, 0, theWindow->width, theWindow->height, 0, 0);

    return(1);          /* ddd: just against warnings */
}

/****************************************************************/

void DrawWall(WindowType theWindow, MeshType *theBox, float c1, float d1,
        float c2, float d2, int wall, int side)           /* ddd */
{
  XPoint  thePoint[4];
 
  if(wall == 0)
  {
    thePoint[0].x= c1*theBox[0].x+d1;  thePoint[0].y= c2*theBox[0].y+d2;
    thePoint[1].x= c1*theBox[1].x+d1;  thePoint[1].y= c2*theBox[1].y+d2;
    thePoint[2].x= c1*theBox[2].x+d1;  thePoint[2].y= c2*theBox[2].y+d2;
    thePoint[3].x= c1*theBox[3].x+d1;  thePoint[3].y= c2*theBox[3].y+d2;
  }
  else if(wall == 1)
  {
    thePoint[0].x= c1*theBox[0].x+d1;  thePoint[0].y= c2*theBox[0].y+d2;
    thePoint[1].x= c1*theBox[1].x+d1;  thePoint[1].y= c2*theBox[1].y+d2;
    thePoint[2].x= c1*theBox[6].x+d1;  thePoint[2].y= c2*theBox[6].y+d2;
    thePoint[3].x= c1*theBox[5].x+d1;  thePoint[3].y= c2*theBox[5].y+d2;
  }
  else if(wall == 2)
  {
    thePoint[0].x= c1*theBox[1].x+d1;  thePoint[0].y= c2*theBox[1].y+d2;
    thePoint[1].x= c1*theBox[2].x+d1;  thePoint[1].y= c2*theBox[2].y+d2;
    thePoint[2].x= c1*theBox[7].x+d1;  thePoint[2].y= c2*theBox[7].y+d2;
    thePoint[3].x= c1*theBox[6].x+d1;  thePoint[3].y= c2*theBox[6].y+d2;
  }
  else if(wall == 3)
  {
    thePoint[0].x= c1*theBox[2].x+d1;  thePoint[0].y= c2*theBox[2].y+d2;
    thePoint[1].x= c1*theBox[3].x+d1;  thePoint[1].y= c2*theBox[3].y+d2;
    thePoint[2].x= c1*theBox[4].x+d1;  thePoint[2].y= c2*theBox[4].y+d2;
    thePoint[3].x= c1*theBox[7].x+d1;  thePoint[3].y= c2*theBox[7].y+d2;
  }
  else if(wall == 4)
  {
    thePoint[0].x= c1*theBox[3].x+d1;  thePoint[0].y= c2*theBox[3].y+d2;
    thePoint[1].x= c1*theBox[0].x+d1;  thePoint[1].y= c2*theBox[0].y+d2;
    thePoint[2].x= c1*theBox[5].x+d1;  thePoint[2].y= c2*theBox[5].y+d2;
    thePoint[3].x= c1*theBox[4].x+d1;  thePoint[3].y= c2*theBox[4].y+d2;
  }
  else if(wall == 5)
  {
    thePoint[0].x= c1*theBox[4].x+d1;  thePoint[0].y= c2*theBox[4].y+d2;
    thePoint[1].x= c1*theBox[5].x+d1;  thePoint[1].y= c2*theBox[5].y+d2;
    thePoint[2].x= c1*theBox[6].x+d1;  thePoint[2].y= c2*theBox[6].y+d2;
    thePoint[3].x= c1*theBox[7].x+d1;  thePoint[3].y= c2*theBox[7].y+d2;
  }

  if(side == BACK)
  {
    XSetForeground(theDisplay, theWindow->xwingc, theBlackPixel);
    XFillPolygon(theDisplay, theWindow->pixmap_buffer,
		 theWindow->xwingc, thePoint, 4, Complex, CoordModeOrigin);
  }
  XSetForeground(theDisplay, theWindow->xwingc, theWhitePixel);
  XDrawLines(theDisplay, theWindow->pixmap_buffer, theWindow->xwingc, thePoint, 4, CoordModeOrigin);
}

/****************************************************************/

void Paint_Button(ButtonType theButton)        /* ddd */
{
  int        upper_shade, upper_mid_shade;
  int        lower_mid_shade, lower_shade;
  int        text_shade, bkgd_shade;
  int        width, height;
  XPoint     X_Points[6];
  XWindowAttributes theWindowAttributes;

  XGetWindowAttributes(theDisplay, theButton->xwin, &theWindowAttributes);
  width  = theWindowAttributes.width;
  height = theWindowAttributes.height;

  if(theButton->state == NORMAL_STATE)
  {
    bkgd_shade  = GrayShade[7];  text_shade      = theBlackPixel;
    upper_shade = GrayShade[10]; upper_mid_shade = GrayShade[9];
    lower_shade = GrayShade[1];  lower_mid_shade = GrayShade[4];
  }
  else if(theButton->state == GRAYED_STATE)
  {
    bkgd_shade  = GrayShade[7];  text_shade      = GrayShade[5];
    upper_shade = GrayShade[10]; upper_mid_shade = GrayShade[9];
    lower_shade = GrayShade[1];  lower_mid_shade = GrayShade[4];
  }
  else
  {
    bkgd_shade  = GrayShade[5];  text_shade      = theWhitePixel;
    upper_shade = GrayShade[2];  upper_mid_shade = GrayShade[5];
    lower_shade = GrayShade[8];  lower_mid_shade = GrayShade[5];
  }
  XSetWindowBackground(theDisplay, theButton->xwin, bkgd_shade);
  XClearWindow(theDisplay, theButton->xwin);
  
  XSetForeground(theDisplay, theButton->xwingc, upper_shade);
  X_Points[0].x= 0;       X_Points[0].y= height;
  X_Points[1].x= 0;       X_Points[1].y= 0;
  X_Points[2].x= width;   X_Points[2].y= 0;
  X_Points[3].x= width-1; X_Points[3].y= 1;
  X_Points[4].x= 1;       X_Points[4].y= 1;
  X_Points[5].x= 1;       X_Points[5].y= height-1;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);

  XSetForeground(theDisplay, theButton->xwingc, upper_mid_shade);
  X_Points[0].x= 2;       X_Points[0].y= height-2;
  X_Points[1].x= 2;       X_Points[1].y= 2;
  X_Points[2].x= width-2; X_Points[2].y= 2;
  X_Points[3].x= width-3; X_Points[3].y= 3;
  X_Points[4].x= 3;       X_Points[4].y= 3;
  X_Points[5].x= 3;       X_Points[5].y= height-3;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);
  
  XSetForeground(theDisplay, theButton->xwingc, upper_mid_shade);
  X_Points[0].x= 4;       X_Points[0].y= height-4;
  X_Points[1].x= 4;       X_Points[1].y= 4;
  X_Points[2].x= width-4; X_Points[2].y= 4;
  X_Points[3].x= width-5; X_Points[3].y= 5;
  X_Points[4].x= 5;       X_Points[4].y= 5;
  X_Points[5].x= 5;       X_Points[5].y= height-5;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);

  XSetForeground(theDisplay, theButton->xwingc, lower_shade);
  X_Points[0].x= 0;       X_Points[0].y= height;
  X_Points[1].x= width;   X_Points[1].y= height;
  X_Points[2].x= width;   X_Points[2].y= 0;
  X_Points[3].x= width-1; X_Points[3].y= 1;
  X_Points[4].x= width-1; X_Points[4].y= height-1;
  X_Points[5].x= 1;       X_Points[5].y= height-1;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);
  
  XSetForeground(theDisplay, theButton->xwingc, lower_mid_shade);
  X_Points[0].x= 2;       X_Points[0].y= height-2;
  X_Points[1].x= width-2; X_Points[1].y= height-2;
  X_Points[2].x= width-2; X_Points[2].y= 2;
  X_Points[3].x= width-3; X_Points[3].y= 3;
  X_Points[4].x= width-3; X_Points[4].y= height-3;
  X_Points[5].x= 3;       X_Points[5].y= height-3;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);

  XSetForeground(theDisplay, theButton->xwingc, lower_mid_shade);
  X_Points[0].x= 4;       X_Points[0].y= height-4;
  X_Points[1].x= width-4; X_Points[1].y= height-4;
  X_Points[2].x= width-4; X_Points[2].y= 4;
  X_Points[3].x= width-5; X_Points[3].y= 5;
  X_Points[4].x= width-5; X_Points[4].y= height-5;
  X_Points[5].x= 5;       X_Points[5].y= height-5;
  XDrawLines(theDisplay, theButton->xwin, theButton->xwingc, X_Points, 6, CoordModeOrigin);

  if(theButton->Label)
  {
    XSetForeground(theDisplay, theButton->xwingc, text_shade);
    if(width > XTextWidth(theFontStruct, theButton->Label, strlen(theButton->Label)))
      XDrawString(theDisplay, theButton->xwin, theButton->xwingc,
		  (width - XTextWidth(theFontStruct, theButton->Label, strlen(theButton->Label)))/2,
		  theFontAscent+8, theButton->Label, strlen(theButton->Label));
    else
      XDrawString(theDisplay, theButton->xwin, theButton->xwingc,
		  width -XTextWidth(theFontStruct, theButton->Label, strlen(theButton->Label)),
		  theFontAscent+8, theButton->Label, strlen(theButton->Label));
  }
}

/****************************************************************/

void Local_Window_Menu(WindowType theWindow, ButtonType theButton)  /* ddd */
{
  switch(theButton->id)
  {
     case WINDOW_MENU_RESCALE:
       if(theOpenDialogBox) SorryMessage(); 
       else
       {
	 theOpenDialogBoxWindow = theWindow;
	 RescaleWindow(); 
       }
       break;
       
     case WINDOW_MENU_TRACE:
       if(Is_Trace_On(theWindow)) Trace_Off(theWindow); 
       else                       Trace_On(theWindow);
       break;
       
     case WINDOW_MENU_PRINT:
       if(theOpenDialogBox) SorryMessage(); 
       else
       {
	 theOpenDialogBoxWindow = theWindow;
	 PostScriptWindow();
       }
       break;

     case WINDOW_MENU_CROSSHAIR:
       if(Is_Crosshair_On(theWindow)) DestroyCrosshair(theWindow);
       else                           Init_Crosshair(theWindow);
       break;

     case WINDOW_MENU_3D_VIEW:
       if(theOpenDialogBox) SorryMessage(); 
       else
       {
	 theOpenDialogBoxWindow = theWindow;
	 Adjust3DViewWindow();
       }
       break;
       
     default:
       break;
  }
}

/****************************************************************/

void Main_Menu(ButtonType theButton)               /* ddd */
{
  switch(theButton->id)
  {
     case MAIN_MENU_RUN:
       if(!theOpenDialogBox && !theCrosshairedWindow) theRunFlag = True;
       break;

     case MAIN_MENU_STOP:
       if(!theOpenDialogBox && !theCrosshairedWindow) theRunFlag = False;
       break;

     case MAIN_MENU_STEP:
       if(!theOpenDialogBox && !theCrosshairedWindow)
       {
	 theRunFlag= False; theStepFlag= True;
       }
       break;
       
     case MAIN_MENU_SAVE:
       if(theOpenDialogBox) SorryMessage(); 
       else                 DialogBox(theDFDB);
       break;
       
     case MAIN_MENU_QUIT:
       if(theOpenDialogBox) SorryMessage(); 
       else                 ExitMessage("Do you really want to exit?");
       break;
       
     default:
       break;
  }
}

/****************************************************************/

void RescaleWindow()
{
  theDialogBoxButtonStart=3;
  if(Is_ThreeD(theOpenDialogBoxWindow))
    sprintf(theRescaleDB->msg, "Rescaling the %s window", theOpenDialogBoxWindow->label->Z_Label);
  else
  sprintf(theRescaleDB->msg, "Rescaling the %s window", theOpenDialogBoxWindow->label->Y_Label);

  if(Is_ThreeD(theOpenDialogBoxWindow))
  {
    theDialogBoxButtonStart=0;
    theRescaleDB->button_list[0].ptr= (char *) &(theOpenDialogBoxWindow->label->Z_Max);
    theRescaleDB->button_list[1].ptr= (char *) &(theOpenDialogBoxWindow->label->Z_Min);
    theRescaleDB->button_list[2].ptr= (char *) &(theOpenDialogBoxWindow->state);
  }
  theRescaleDB->button_list[3].ptr= (char *) &(theOpenDialogBoxWindow->label->Y_Max);
  theRescaleDB->button_list[4].ptr= (char *) &(theOpenDialogBoxWindow->label->Y_Min);
  theRescaleDB->button_list[5].ptr= (char *) &(theOpenDialogBoxWindow->state);
  theRescaleDB->button_list[6].ptr= (char *) &(theOpenDialogBoxWindow->label->X_Max);
  theRescaleDB->button_list[7].ptr= (char *) &(theOpenDialogBoxWindow->label->X_Min);
  theRescaleDB->button_list[8].ptr= (char *) &(theOpenDialogBoxWindow->state);
  
  DialogBox(theRescaleDB);
}

/****************************************************************/

void PostScriptWindow()
{
  if(Is_ThreeD(theOpenDialogBoxWindow))
    sprintf(thePSDB->msg, "Write the %s window into a PostScript file",
	    theOpenDialogBoxWindow->label->Z_Label);
  else
    sprintf(thePSDB->msg, "Write the %s window into a PostScript file",
	    theOpenDialogBoxWindow->label->Y_Label);
  thePSDB->button_list[0].ptr= theOpenDialogBoxWindow->ps_file_name;
  thePSDB->button_list[1].ptr= theOpenDialogBoxWindow->plot_title;
  DialogBox(thePSDB);
}

/****************************************************************/

void Adjust3DViewWindow()
{
  sprintf(theThreeDViewDB->msg, "Adjusting the 3D view for the %s window",
	  theOpenDialogBoxWindow->label->Z_Label);
  theThreeDViewDB->button_list[0].ptr= (char *) &(theOpenDialogBoxWindow->theta);
  theThreeDViewDB->button_list[1].ptr= (char *) &(theOpenDialogBoxWindow->phi);
  theThreeDViewDB->button_list[2].ptr= (char *) &(theOpenDialogBoxWindow->state);
  theThreeDViewDB->button_list[3].ptr= (char *) &(theOpenDialogBoxWindow->state);
  theThreeDViewDB->button_list[4].ptr= (char *) &(theOpenDialogBoxWindow->state);
  
  DialogBox(theThreeDViewDB);
}

/****************************************************************/

void ExitMessage(char *Message)                /* ddd */
{
  theMessageDB->button_list[0].name= "Exit   ";
  strcpy(theMessageDB->msg, Message);
  DialogBox(theMessageDB);
}

/****************************************************************/

void Init_Crosshair(WindowType theWindow)     /* ddd */
{
  XSetWindowAttributes  theSetWindowAttributes;
  XSizeHints            theSizeHints;
  unsigned long         theWindowMask;
  XWMHints              theWMHints;
  XGCValues             theGCValues;
  ButtonType            theButtonListPtr, theButtonListPrevPtr;
  int                   i, x, y;

  if(theCrosshairedWindow)
  {
#ifdef SOUND
    system(Sound2);
#endif
    printf("XGrafix: Can't crosshair more than one window at a time!!\n");
    printf(" This option should be available in the next version..\n");
    return;
  }

  if(!theOpenDialogBox)
  {
    thePrevRunFlag = theRunFlag;
    theRunFlag     = False;
  }
  theCrosshairedWindow = theWindow;
  Crosshair_On(theCrosshairedWindow);
  XDefineCursor(theDisplay, theWindow->xwin, theCrosshairCursor);
  
  XGetNormalHints(theDisplay, theWindow->xwin, &theSizeHints);

  if((x = theSizeHints.x -203) < 0) x= theSizeHints.x +theSizeHints.width +10;
  y= theSizeHints.y;
  
  /*******************************************************/
  /* Setting the xy cross-hair window's attributes and creating it  */
  
  theSetWindowAttributes.border_pixel     = theWhitePixel;
  theSetWindowAttributes.background_pixel = theBlackPixel;
  theWindowMask = (CWBackPixel | CWBorderPixel);

  theXYCrosshairWindow.xwin = XCreateWindow(theDisplay, theRootWindow, x, y,
					    200, 2*(theFontHeight+19), 2,
					    theDepth, InputOutput, CopyFromParent,
					    theWindowMask, &theSetWindowAttributes);
  
  /********************************************************/
  /* Setting the window manager's hints for the xy cross-hair window */
  
  theWMHints.initial_state = NormalState;
  theWMHints.icon_pixmap   = theIcon;
  theWMHints.flags         = IconPixmapHint | StateHint;
  
  XSetWMHints(theDisplay, theXYCrosshairWindow.xwin, &theWMHints);

  /*********************************/
  /* Setting the xy cross-hair window's name  */
  
  XStoreName(theDisplay, theXYCrosshairWindow.xwin, "Crosshair Coordinates");
  
  /****************************************/
  /* Setting the size and normal hints    */

  theSizeHints.flags  = USPosition | USSize;
  theSizeHints.x      = x;
  theSizeHints.y      = y;
  theSizeHints.width  = 200; 
  theSizeHints.height = 2*(theFontHeight+19);
  
  XSetNormalHints( theDisplay, theXYCrosshairWindow.xwin, &theSizeHints);
  
  XSelectInput(theDisplay, theXYCrosshairWindow.xwin,
	       StructureNotifyMask | ExposureMask | SubstructureNotifyMask);
  
  /********************************************/
  /* Setting up the buttons for the xy cross-hair window */

  theButtonListPrevPtr = NULL;
  for(i=0; i< MAX_CROSSHAIR_BUTTON; i++)
  {
    if (!(theButtonListPtr = (ButtonType)malloc(sizeof(struct win_button))))
      puts("XGrafix(Init_Crosshair): Not enough memory to allocate a new button");
    
    theButtonListPtr->state = PUSHED_STATE;

    if(i== CROSSHAIR_X_FIELD)
    { strcpy(theButtonListPtr->Label, "X = 0.0");   theButtonListPtr->id = CROSSHAIR_X_FIELD;
    }
    else if(i== CROSSHAIR_Y_FIELD)
    { strcpy(theButtonListPtr->Label, "Y = 0.0");   theButtonListPtr->id = CROSSHAIR_Y_FIELD;
    }
    
    theButtonListPtr->xwin  = XCreateSimpleWindow(theDisplay, theXYCrosshairWindow.xwin,
						  0, i*(theFontHeight+19),
						  198, theFontHeight+16, 1,
						  GrayShade[5], theBlackPixel);
    
    XSelectInput(theDisplay, theButtonListPtr->xwin,
		 ButtonPressMask | ButtonReleaseMask | ExposureMask);
    
    theButtonListPtr->xwingc = XCreateGC(theDisplay, theButtonListPtr->xwin,
					 (unsigned long) 0, &theGCValues);
    XSetFont(theDisplay, theButtonListPtr->xwingc, theFont);
    theButtonListPtr->next= theButtonListPrevPtr;
    theButtonListPrevPtr = theButtonListPtr;
  }
  theXYCrosshairWindow.button_list= theButtonListPtr;
  SetCrosshairParameters();
  XMapSubwindows(theDisplay, theXYCrosshairWindow.xwin);
  XMapWindow(theDisplay, theXYCrosshairWindow.xwin);
}

/****************************************************************/


void UpdateCrosshair(int x, int y)    /* ddd */
{
  ButtonType theButtonPtr;

  if(x <theCrosshairx1 || x >theCrosshairx2 || y <theCrosshairy1 || y >theCrosshairy2)  return;
  
  /*****************************/
  /* Updating the Coordinates. */
  
  for(theButtonPtr = theXYCrosshairWindow.button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
  {
    if(theButtonPtr->id == CROSSHAIR_X_FIELD)
    {
      if(Is_X_Log(theCrosshairedWindow))
	sprintf(theButtonPtr->Label, "X = %g", pow(10.0, x*theCrosshairmx+theCrosshairbx));
      else
	sprintf(theButtonPtr->Label, "X = %g", x*theCrosshairmx+theCrosshairbx);
    }
    else if(theButtonPtr->id == CROSSHAIR_Y_FIELD)
    {
      if(Is_Y_Log(theCrosshairedWindow))
	sprintf(theButtonPtr->Label, "Y = %g", pow(10.0, y*theCrosshairmy+theCrosshairby));
      else
	sprintf(theButtonPtr->Label, "Y = %g", y*theCrosshairmy+theCrosshairby);
    }
    Paint_Button(theButtonPtr);
  }
}

/****************************************************************/

void SetCrosshairParameters()
{
  LabelType label_Ptr;
  
  theCrosshairx1 = theCrosshairedWindow->ulxc+1;
  theCrosshairy1 = theCrosshairedWindow->ulyc+1;
  theCrosshairx2 = theCrosshairedWindow->lrxc-1;
  theCrosshairy2 = theCrosshairedWindow->lryc-1;
  
  label_Ptr= theCrosshairedWindow->label;

  if(Is_X_Log(theCrosshairedWindow))
  {
    theCrosshairmx = log10(label_Ptr->X_Max/label_Ptr->X_Min)/(theCrosshairx2 -theCrosshairx1);
    theCrosshairbx = (log10(label_Ptr->X_Min)*theCrosshairx2 
		      -log10(label_Ptr->X_Max)*theCrosshairx1)/(theCrosshairx2 -theCrosshairx1);
  }
  else
  {
    theCrosshairmx = (label_Ptr->X_Max -label_Ptr->X_Min)/(theCrosshairx2 -theCrosshairx1);
    theCrosshairbx = (label_Ptr->X_Min*theCrosshairx2 
		      -label_Ptr->X_Max*theCrosshairx1)/(theCrosshairx2 -theCrosshairx1);
  }
  if(Is_Y_Log(theCrosshairedWindow))
  {
    theCrosshairmy = log10(label_Ptr->Y_Max/label_Ptr->Y_Min)/(theCrosshairy1 -theCrosshairy2);
    theCrosshairby = (log10(label_Ptr->Y_Min)*theCrosshairy1 
		      -log10(label_Ptr->Y_Max)*theCrosshairy2)/(theCrosshairy1 -theCrosshairy2);
  }
  else
  {
    theCrosshairmy = (label_Ptr->Y_Max -label_Ptr->Y_Min)/(theCrosshairy1 -theCrosshairy2);
    theCrosshairby = (label_Ptr->Y_Min*theCrosshairy1 
		      -label_Ptr->Y_Max*theCrosshairy2)/(theCrosshairy1 -theCrosshairy2);
  }
}

/****************************************************************/

void DestroyCrosshair(WindowType theWindow)       /* ddd */
{
  ButtonType theButtonPtr;

  Crosshair_Off(theCrosshairedWindow);
  XUndefineCursor(theDisplay, theCrosshairedWindow->xwin);
  theCrosshairedWindow = NULL;

  if(!theOpenDialogBox) theRunFlag = thePrevRunFlag;
  
  for(theButtonPtr = theXYCrosshairWindow.button_list; theButtonPtr != NULL; theButtonPtr = theButtonPtr->next)
  {
    XFreeGC(theDisplay, theButtonPtr->xwingc);
    XDestroyWindow(theDisplay, theButtonPtr->xwin);
  }
  XDestroyWindow(theDisplay, theXYCrosshairWindow.xwin);
}

/****************************************************************/

void Init_Rescale_DialogBox()
{  
  theRescaleDB = (DialogBoxType)malloc(sizeof(struct dialogbox));
  
  theRescaleDB->number = 11;
  theRescaleDB->name   = "Rescale Dialog Box";
  theRescaleDB->button_list= (DialogBoxItemType)malloc(theRescaleDB->number*sizeof(struct dialogbox_item));

  theRescaleDB->button_list[0].type= FLOAT;
  theRescaleDB->button_list[0].name= "zmax";
  theRescaleDB->button_list[0].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[1].type= FLOAT;
  theRescaleDB->button_list[1].name= "zmin";
  theRescaleDB->button_list[1].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[2].type= Z_AUTORESCALE;
  theRescaleDB->button_list[2].name= "Autorescale Z";
  theRescaleDB->button_list[2].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theRescaleDB->button_list[3].type= FLOAT;
  theRescaleDB->button_list[3].name= "ymax";
  theRescaleDB->button_list[3].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[4].type= FLOAT;
  theRescaleDB->button_list[4].name= "ymin";
  theRescaleDB->button_list[4].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[5].type= Y_AUTORESCALE;
  theRescaleDB->button_list[5].name= "Autorescale Y";
  theRescaleDB->button_list[5].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[6].type= FLOAT;
  theRescaleDB->button_list[6].name= "xmax";
  theRescaleDB->button_list[6].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theRescaleDB->button_list[7].type= FLOAT;
  theRescaleDB->button_list[7].name= "xmin";
  theRescaleDB->button_list[7].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theRescaleDB->button_list[8].type= X_AUTORESCALE;
  theRescaleDB->button_list[8].name= "Autorescale X";
  theRescaleDB->button_list[8].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theRescaleDB->button_list[9].type= NULLTYPE;
  theRescaleDB->button_list[9].name= NULL;
  theRescaleDB->button_list[9].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theRescaleDB->button_list[10].type= NULLTYPE;
  theRescaleDB->button_list[10].name= NULL;
  theRescaleDB->button_list[10].xbutton= (ButtonType)malloc(sizeof(struct win_button));
}

/****************************************************************/

void Init_ThreeDView_DialogBox()
{  
  theThreeDViewDB = (DialogBoxType)malloc(sizeof(struct dialogbox));
  
  theThreeDViewDB->number = 7;
  theThreeDViewDB->name   = "ThreeDView Dialog Box";
  theThreeDViewDB->button_list= (DialogBoxItemType)malloc(theThreeDViewDB->number*sizeof(struct dialogbox_item));

  theThreeDViewDB->button_list[0].type= FLOAT;
  theThreeDViewDB->button_list[0].name= "theta";
  theThreeDViewDB->button_list[0].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theThreeDViewDB->button_list[1].type= FLOAT;
  theThreeDViewDB->button_list[1].name= "phi";
  theThreeDViewDB->button_list[1].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theThreeDViewDB->button_list[2].type= SHADING;
  theThreeDViewDB->button_list[2].name= "Shading";
  theThreeDViewDB->button_list[2].xbutton= (ButtonType)malloc(sizeof(struct win_button));
  
  theThreeDViewDB->button_list[3].type= COLORCODE;
  theThreeDViewDB->button_list[3].name= "Color Code";
  theThreeDViewDB->button_list[3].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theThreeDViewDB->button_list[4].type= GRID;
  theThreeDViewDB->button_list[4].name= "Grid";
  theThreeDViewDB->button_list[4].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theThreeDViewDB->button_list[5].type= NULLTYPE;
  theThreeDViewDB->button_list[5].name= NULL;
  theThreeDViewDB->button_list[5].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theThreeDViewDB->button_list[6].type= NULLTYPE;
  theThreeDViewDB->button_list[6].name= NULL;
  theThreeDViewDB->button_list[6].xbutton= (ButtonType)malloc(sizeof(struct win_button));
}

/****************************************************************/

void Init_DF_DialogBox()
{       
  theDFDB = (DialogBoxType)malloc(sizeof(struct dialogbox));	
    
  theDFDB->number = 3;
  theDFDB->name   = "Save Dialog Box";
  sprintf(theDFDB->msg, "Dumping the present state into a file");
  theDFDB->button_list= (DialogBoxItemType)malloc(theDFDB->number*sizeof(struct dialogbox_item));	
  
  theDFDB->button_list[0].type= CHAR;
  theDFDB->button_list[0].name= "File name";
  theDFDB->button_list[0].ptr= theDumpFile;
  theDFDB->button_list[0].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theDFDB->button_list[1].type= NULLTYPE;
  theDFDB->button_list[1].name= NULL;
  theDFDB->button_list[1].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theDFDB->button_list[2].type= NULLTYPE;
  theDFDB->button_list[2].name= NULL;
  theDFDB->button_list[2].xbutton= (ButtonType)malloc(sizeof(struct win_button));
}

/****************************************************************/

void Init_PS_DialogBox()
{  
  thePSDB = (DialogBoxType)malloc(sizeof(struct dialogbox));	
    
  thePSDB->number = 4;
  thePSDB->name   = "PostScript Dialog Box";
  thePSDB->button_list= (DialogBoxItemType)malloc(thePSDB->number*sizeof(struct dialogbox_item));	

  thePSDB->button_list[0].type= CHAR;
  thePSDB->button_list[0].name= "File name";
  thePSDB->button_list[0].ptr= thePSFile;
  thePSDB->button_list[0].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  thePSDB->button_list[1].type= CHAR;
  thePSDB->button_list[1].name= "Plot title";
  thePSDB->button_list[1].ptr= thePSFile;
  thePSDB->button_list[1].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  thePSDB->button_list[2].type= NULLTYPE;
  thePSDB->button_list[2].name= NULL;
  thePSDB->button_list[2].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  thePSDB->button_list[3].type= NULLTYPE;
  thePSDB->button_list[3].name= NULL;
  thePSDB->button_list[3].xbutton= (ButtonType)malloc(sizeof(struct win_button));
}

/****************************************************************/

void Init_Message_DialogBox()
{
  theMessageDB = (DialogBoxType)malloc(sizeof(struct dialogbox));	

  theMessageDB->number     = 2;
  theMessageDB->name       = "Message Dialog Box";
  theMessageDB->button_list= (DialogBoxItemType)malloc(theMessageDB->number*sizeof(struct dialogbox_item));

  theMessageDB->button_list[0].type= NULLTYPE;
  theMessageDB->button_list[0].name= NULL;
  theMessageDB->button_list[0].xbutton= (ButtonType)malloc(sizeof(struct win_button));

  theMessageDB->button_list[1].type= NULLTYPE;
  theMessageDB->button_list[1].name= NULL;
  theMessageDB->button_list[1].xbutton= (ButtonType)malloc(sizeof(struct win_button));
}

/****************************************************************/

void SorryMessage()
{
#ifdef SOUND
  system(Sound1);
#endif
  printf("DialogBox(): One dialog box is already open. Can't open another one!\n");
}

/****************************************************************/

void DialogBox(DialogBoxType theDialogBox)          /* ddd */
{
  XSetWindowAttributes  theWindowAttributes;
  XSizeHints            theSizeHints;
  unsigned long         theWindowMask;
  XWMHints              theWMHints;
  XGCValues             theGCValues;
  
  int button_x, button_y, button_width, button_height;
  int i, width=0, height;

  /**************************************/
  theOpenDialogBox= theDialogBox;

  if(!theCrosshairedWindow)
  {
    thePrevRunFlag = theRunFlag;
    theRunFlag     = False;
  }

  /**************************************/
  /* Getting the size of the dialog box */
  
  for(i= theDialogBoxButtonStart; i< theDialogBox->number; i++)
    if(theDialogBox->button_list[i].name)
      width= max(width, XTextWidth(theFontStruct, theDialogBox->button_list[i].name, 
				   strlen(theDialogBox->button_list[i].name)));
  
  button_x     = 10 +width +10;
  button_y     = theDialogBoxButtonLabelY -theFontAscent-10;
  button_width = 200;
  button_height= theFontHeight +16;
 
  theDialogBox->width = max(width+40+button_width, 
			    20+XTextWidth(theFontStruct, theDialogBox->msg, 
					  strlen(theDialogBox->msg)));
  height= button_y +(theDialogBox->number -theDialogBoxButtonStart)*theDialogBoxButtonSpacing;
  
  /********************************************/
  /* Setting the Attributes of the dialog box */
  
  theWindowAttributes.border_pixel     = theWhitePixel;
  theWindowAttributes.background_pixel = GrayShade[3];
  theWindowMask = (CWBackPixel | CWBorderPixel);
  
  theDialogBox->xwin = XCreateWindow(theDisplay, theRootWindow, DEFAULT_DIALOGBOX_X,
				     DEFAULT_DIALOGBOX_Y, theDialogBox->width, height,
				     DEFAULT_WIN_BORDER_WIDTH, theDepth,
				     InputOutput, CopyFromParent,
				     theWindowMask, &theWindowAttributes);
  
  /*********************************************************/
  /* Setting the window manager's hints for the dialog box */
  
  theWMHints.initial_state = NormalState;
  theWMHints.icon_pixmap   = theIcon;
  theWMHints.flags         = IconPixmapHint | StateHint;
  
  XSetWMHints(theDisplay, theDialogBox->xwin, &theWMHints);
  XStoreName(theDisplay, theDialogBox->xwin, theDialogBox->name);
 
  /********************************************************/
  /* Setting the size and normal hints for the dialog box */

  theSizeHints.flags  = USPosition | USSize;
  theSizeHints.x      = DEFAULT_DIALOGBOX_X;
  theSizeHints.y      = DEFAULT_DIALOGBOX_Y;
  theSizeHints.width  = theDialogBox->width;
  theSizeHints.height = height;
  
  XSetNormalHints( theDisplay, theDialogBox->xwin, &theSizeHints);
  
  /****************************************/
  /* Initializing a GC for the dialog box */
  
  theDialogBox->xwingc = XCreateGC(theDisplay, theDialogBox->xwin,
				   (unsigned long) 0, &theGCValues);
  if (theDialogBox->xwingc)
  {
    XSetForeground(theDisplay, theDialogBox->xwingc, theWhitePixel);
    XSetBackground(theDisplay, theDialogBox->xwingc, theBlackPixel);
  }
  else
  {
    printf("XGrafix: can't create a GC for the Dialogbox");
    XDestroyWindow(theDisplay, theDialogBox->xwin);
  }
  XSetFont(theDisplay, theDialogBox->xwingc, theFont);
  XSelectInput(theDisplay, theDialogBox->xwin,
	       StructureNotifyMask | ExposureMask | SubstructureNotifyMask);
  
  /**************************************/
  /* defining buttons of the dialog box */
 
  for(i=theDialogBoxButtonStart; i< theDialogBox->number; i++)
  {
    theDialogBox->button_list[i].xbutton->state= NORMAL_STATE;
    if(theDialogBox->button_list[i].type == FLOAT)
      sprintf(theDialogBox->button_list[i].xbutton->Label, "%g",
	      *((float *)theDialogBox->button_list[i].ptr)); 
    
    else if(theDialogBox->button_list[i].type == INTEGER)
      sprintf(theDialogBox->button_list[i].xbutton->Label, "%d",
	      *((int *)theDialogBox->button_list[i].ptr)); 
    
    else if(theDialogBox->button_list[i].type == CHAR)
      sprintf(theDialogBox->button_list[i].xbutton->Label, "%s",
	      theDialogBox->button_list[i].ptr); 
    
    else if(theDialogBox->button_list[i].type%2 == 0 && i< theDialogBox->number-2)
    {
      if(theDialogBox->button_list[i].type & *((int *)theDialogBox->button_list[i].ptr))
	sprintf(theDialogBox->button_list[i].xbutton->Label, "%s", "ON"); 
      else
	sprintf(theDialogBox->button_list[i].xbutton->Label, "%s", "OFF"); 
    }
    else if(i == theDialogBox->number-2)
      sprintf(theDialogBox->button_list[i].xbutton->Label, "%s", "OK"); 
    else if(i == theDialogBox->number-1)
      sprintf(theDialogBox->button_list[i].xbutton->Label, "%s", "CANCEL"); 
    
    theDialogBox->button_list[i].xbutton->xwin  = XCreateSimpleWindow(theDisplay, theDialogBox->xwin, button_x, button_y
								      +(i-theDialogBoxButtonStart)*theDialogBoxButtonSpacing,
								      button_width, button_height,
								      2, GrayShade[5], theBlackPixel);
    
    XSelectInput(theDisplay, theDialogBox->button_list[i].xbutton->xwin,
		 ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask);
    
    theDialogBox->button_list[i].xbutton->xwingc = XCreateGC(theDisplay,
							     theDialogBox->button_list[i].xbutton->xwin,
							     (unsigned long) 0, &theGCValues);
    
    XSetFont(theDisplay, theDialogBox->button_list[i].xbutton->xwingc, theFont);
    XDefineCursor(theDisplay, theDialogBox->button_list[i].xbutton->xwin, theButtonCursor);
  }
  
  /**********************************************/
  /* Mapping the Window and dumping stuff in it */
  
  XMapSubwindows(theDisplay, theDialogBox->xwin);
  XMapWindow(theDisplay, theDialogBox->xwin);
}

/*****************************************************************/

void Paint_DialogBox(DialogBoxType theDialogBox)      /* ddd */
{
  int i, msg_length;
  
  XSetForeground(theDisplay, theDialogBox->xwingc, theDBTextColor);
  msg_length= XTextWidth(theFontStruct, theDialogBox->msg, strlen(theDialogBox->msg));
  XDrawString(theDisplay, theDialogBox->xwin, theDialogBox->xwingc, (theDialogBox->width -msg_length)/2, 
	      theFontHeight+6, theDialogBox->msg, strlen(theDialogBox->msg));
  
  for(i=theDialogBoxButtonStart; i< theDialogBox->number; i++)
    if(theDialogBox->button_list[i].name)
      XDrawString(theDisplay, theDialogBox->xwin, theDialogBox->xwingc,
		  theDialogBoxButtonLabelX, theDialogBoxButtonLabelY +
		  (i-theDialogBoxButtonStart)*theDialogBoxButtonSpacing,
		  theDialogBox->button_list[i].name, strlen(theDialogBox->button_list[i].name));
}

/****************************************************************/

void DialogBox_Menu(DialogBoxType theDialogBox)      /* ddd */
{
  int i, theButtonNumber;
  
  for(i=theDialogBoxButtonStart; i< theDialogBox->number; i++)
    if(theDialogBox->button_list[i].xbutton->state == PUSHED_STATE) { theButtonNumber= i; break;}
  
  if(theButtonNumber == theDialogBox->number-2)          /* OK button */
  {
    for(i=theDialogBoxButtonStart; i< theDialogBox->number-2; i++)
    {
      if(theDialogBox->button_list[i].type == FLOAT)
	sscanf(theDialogBox->button_list[i].xbutton->Label, "%g", (float *)theDialogBox->button_list[i].ptr);
      
      else if(theDialogBox->button_list[i].type == INTEGER)
	sscanf(theDialogBox->button_list[i].xbutton->Label, "%d", (int *)theDialogBox->button_list[i].ptr);
      
      else if(theDialogBox->button_list[i].type == CHAR)
	strcpy(theDialogBox->button_list[i].ptr, theDialogBox->button_list[i].xbutton->Label);
      
      else if(theDialogBox->button_list[i].type%2 == 0)
      { 
	if(!strcmp(theDialogBox->button_list[i].xbutton->Label, "ON"))
	  *((int *)theDialogBox->button_list[i].ptr) |= theDialogBox->button_list[i].type;
	else
	  *((int *)theDialogBox->button_list[i].ptr) &= ~(theDialogBox->button_list[i].type);
      }
    }
    DispatchMessage(theDialogBox);
    DestroyDialogBox(theDialogBox);
  }
  else if(theButtonNumber == theDialogBox->number-1)     /* CANCEL button */
    DestroyDialogBox(theDialogBox);
  
  else if(theDialogBox->button_list[theButtonNumber].type%2 == 0)
  {
    if(!strcmp(theDialogBox->button_list[theButtonNumber].xbutton->Label, "ON"))
      sprintf(theDialogBox->button_list[theButtonNumber].xbutton->Label, "%s", "OFF"); 
    else
      sprintf(theDialogBox->button_list[theButtonNumber].xbutton->Label, "%s", "ON"); 
    
    theOpenDialogBox->button_list[theButtonNumber].xbutton->state = NORMAL_STATE;
    Paint_Button(theOpenDialogBox->button_list[theButtonNumber].xbutton);
  }
}

/****************************************************************/

void DispatchMessage(DialogBoxType theDialogBox)     /* ddd */
{
  WindowType theWindowPtr;
  
  if(!strcmp(theDialogBox->name, "Rescale Dialog Box"))
  {
    if(Is_Y_AutoRescale_Before(theOpenDialogBoxWindow) &&
       !Is_Y_AutoRescale(theOpenDialogBoxWindow))
      Y_AutoRescale_Off_Before(theOpenDialogBoxWindow);
    
    if(Is_X_AutoRescale_Before(theOpenDialogBoxWindow) &&
       !Is_X_AutoRescale(theOpenDialogBoxWindow))
      X_AutoRescale_Off_Before(theOpenDialogBoxWindow);

    if(theOpenDialogBoxWindow->pixmap_buffer)
    {
      XFreePixmap(theDisplay, theOpenDialogBoxWindow->pixmap_buffer);
      theOpenDialogBoxWindow->pixmap_buffer = NULL;
    }
    Iconic_Before(theOpenDialogBoxWindow);
    (*(theOpenDialogBoxWindow->paint_function))(theOpenDialogBoxWindow);
    if(theCrosshairedWindow == theOpenDialogBoxWindow) SetCrosshairParameters();
  }
  else if(!strcmp(theDialogBox->name, "ThreeDView Dialog Box"))
  {
    if(theOpenDialogBoxWindow->pixmap_buffer)
    {
      XFreePixmap(theDisplay, theOpenDialogBoxWindow->pixmap_buffer);
      theOpenDialogBoxWindow->pixmap_buffer = NULL;
    }
    Iconic_Before(theOpenDialogBoxWindow);
    (*(theOpenDialogBoxWindow->paint_function))(theOpenDialogBoxWindow);
    
    if(theCrosshairedWindow == theOpenDialogBoxWindow) SetCrosshairParameters();
  }
  
  else if(!strcmp(theDialogBox->name, "Save Dialog Box"))
    Dump(theDumpFile);
  
  else if(!strcmp(theDialogBox->name, "PostScript Dialog Box"))
    (*(theOpenDialogBoxWindow->print_function))();
  
  else if(!strcmp(theDialogBox->name, "Message Dialog Box"))
  {

#ifdef SOUND
    system(Sound4);
#endif
    for(theWindowPtr = theWindowList; theWindowPtr != NULL; theWindowPtr = theWindowPtr->next)
    {
      if(theWindowPtr->pixmap_buffer) XFreePixmap(theDisplay, theWindowPtr->pixmap_buffer);
      XFreeGC(theDisplay, theWindowPtr->xwingc);
    }
    exit(1);
  }
}

/****************************************************************/

void DestroyDialogBox(DialogBoxType theDialogBox)    /* ddd */
{
  int i;
  
  theOpenDialogBox= NULL;
  theOpenDialogBoxWindow = NULL;
  
  if(!theCrosshairedWindow)
    theRunFlag = thePrevRunFlag;
  
  for(i=theDialogBoxButtonStart; i< theDialogBox->number; i++)
  {
    XFreeGC(theDisplay,  theDialogBox->button_list[i].xbutton->xwingc);
    XDestroyWindow(theDisplay, theDialogBox->button_list[i].xbutton->xwin);
  }
   
  theDialogBoxButtonStart=0;
  XFreeGC(theDisplay,  theDialogBox->xwingc);
  XDestroyWindow(theDisplay, theDialogBox->xwin);
}

/****************************************************************/

void ReadFromKeyborad(XKeyEvent *theXKeyEvent)       /* ddd */
{
  char   theChar;
  int    i, theType, theButtonNumber;
  KeySym theKeySym;

  for(i=theDialogBoxButtonStart; i< theOpenDialogBox->number; i++)
    if(theOpenDialogBox->button_list[i].xbutton->state == PUSHED_STATE) { theButtonNumber= i; break;}

  theType = theOpenDialogBox->button_list[theButtonNumber].type;
  if(!theType) return;
  theChar =0;
  XLookupString(theXKeyEvent, &theChar, 1, &theKeySym, NULL);
  i= strlen(theOpenDialogBox->button_list[theButtonNumber].xbutton->Label);
  
  switch(theKeySym)
  {
    case XK_BackSpace:
    case XK_Delete:
      if(i) theOpenDialogBox->button_list[theButtonNumber].xbutton->Label[i-1]=0;
      Paint_Button(theOpenDialogBox->button_list[theButtonNumber].xbutton);
      break;
    
    case XK_Return:
      theOpenDialogBox->button_list[theButtonNumber].xbutton->state = NORMAL_STATE;
      Paint_Button(theOpenDialogBox->button_list[theButtonNumber].xbutton);
      break; 
      
    default:
      if(i<MAX_BUFFER_SIZE-1)
      {
	if(theType == FLOAT &&
	   ((theChar>=48 && theChar<= 57) || theChar== 'e' ||
	    theChar== 'E' || theChar== '.' || theChar== '-' || theChar== '+'))
	  theOpenDialogBox->button_list[theButtonNumber].xbutton->Label[i]= theChar;
	
	else if(theType == INTEGER &&
		((theChar>=48 && theChar<= 57) || theChar== '-' || theChar== '+'))
	  theOpenDialogBox->button_list[theButtonNumber].xbutton->Label[i]= theChar;
	
	else if(theType == CHAR &&
		theChar >= 32 && theChar <= 125)
	  theOpenDialogBox->button_list[theButtonNumber].xbutton->Label[i]= theChar;

	theOpenDialogBox->button_list[theButtonNumber].xbutton->Label[i+1]= 0;
	Paint_Button(theOpenDialogBox->button_list[theButtonNumber].xbutton);
      }
      break;
    }
}      

/****************************************************************/

#define	NPOINTMAX   500
FILE *fp;

int PostScriptOpenWindow()
{
  DataType  data_Ptr, ptr;
  LabelType label_Ptr;
  int       i, j, n, nplot;
  int       x1, x2, y1, y2;
  float     dtick, bx, by, mx, my;
  MeshType  *M_Point;

  if(!(fp= fopen(theOpenDialogBoxWindow->ps_file_name, "w"))) 
  {
    printf("PostScriptOpenWindow(): File was not opened properly!");
    return(1);            /* ddd: just against warnings */
  }
  PSHeader();

  /*****************************/

  data_Ptr = theOpenDialogBoxWindow->data;
  label_Ptr= theOpenDialogBoxWindow->label;
  
  x1 = 108;     x2 = 684;
  y1 = 108;     y2 = 504;

  fprintf(fp, "612 0 translate\n");
  fprintf(fp, "90 rotate\n");
  
  fprintf(fp, "1 setlinewidth\n");
  fprintf(fp, "0 setgray\n");

  fprintf(fp, "1 %d %d %d %d rectangle\n", x1, y1, x2, y2);
  
  /************************/
  /* Printing the labels */

  fprintf(fp, "90 rotate\n");
  fprintf(fp, "/Times-BoldItalic findfont 12 scalefont setfont\n");
  fprintf(fp, "306 -100 moveto\n");
  fprintf(fp, "(%s) prtstrfrommidlow\n", label_Ptr->Y_Label);
  fprintf(fp, "-90 rotate\n");
  
  fprintf(fp, "396 92 moveto\n");
  fprintf(fp, "(%s) prtstrfrommidup\n", label_Ptr->X_Label);

  fprintf(fp, "/Times-Bold findfont 12 scalefont setfont\n");
  fprintf(fp, "108 92 moveto\n");
  fprintf(fp, "(%.3G) prtstrfromlftup\n", label_Ptr->X_Min);
  fprintf(fp, "684 92 moveto\n");
  fprintf(fp, "(%.3G) prtstrfromritup\n", label_Ptr->X_Max);

  fprintf(fp, "396 512 moveto\n");
  fprintf(fp, "/Times-Bold findfont 14 scalefont setfont\n");
  fprintf(fp, "(%s) prtstrfrommidlow\n", theOpenDialogBoxWindow->plot_title);

  fprintf(fp, "/Times-Bold findfont 12 scalefont setfont\n");
  fprintf(fp, "100 495 moveto\n");
  fprintf(fp, "(%.3G) prtstrfromritup\n", label_Ptr->Y_Max);
  fprintf(fp, "100 108 moveto\n");
  fprintf(fp, "(%.3G) prtstrfromritlow\n", label_Ptr->Y_Min);

  if(label_Ptr->Y_Max == label_Ptr->Y_Min || label_Ptr->X_Max == label_Ptr->X_Min) return(1);
						/* ddd: just against warnings */

  /***************************/
  /* Drawing the tick marks  */

  fprintf(fp, "gsave 0 setgray .8 setlinewidth\n");

  if(Is_Y_Log(theOpenDialogBoxWindow))
  {
    dtick = log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
    for(i=1; i< dtick; i++)
    {
      fprintf(fp, "%d %g moveto\n", x1,   y1+i*(y2-y1)/dtick);
      fprintf(fp, "%d %g lineto\n", x1+4, y1+i*(y2-y1)/dtick);
      
      fprintf(fp, "%d %g moveto\n", x2-4, y1+i*(y2-y1)/dtick);
      fprintf(fp, "%d %g lineto\n", x2,   y1+i*(y2-y1)/dtick);
    }
  }
  else if( (label_Ptr->Y_Min < 0.0 && 0.0 < label_Ptr->Y_Max) ||
	  (label_Ptr->Y_Max < 0.0 && 0.0 < label_Ptr->Y_Min))
  {
    dtick = (y2-y1)/(label_Ptr->Y_Max -label_Ptr->Y_Min);
    fprintf(fp, "%d %g moveto\n", x1,   y2-dtick*(label_Ptr->Y_Max));
    fprintf(fp, "%d %g lineto\n", x1+4, y2-dtick*(label_Ptr->Y_Max));

    fprintf(fp, "%d %g moveto\n", x2-4, y2-dtick*(label_Ptr->Y_Max));
    fprintf(fp, "%d %g lineto\n", x2,   y2-dtick*(label_Ptr->Y_Max));
  }

  if(Is_X_Log(theOpenDialogBoxWindow))
  {
    dtick = log10(label_Ptr->X_Max/label_Ptr->X_Min);
    for(i=1; i< dtick; i++)
    {
      fprintf(fp, "%g %d moveto\n", x1+i*(x2-x1)/dtick, y2);
      fprintf(fp, "%g %d lineto\n", x1+i*(x2-x1)/dtick, y2-4);
      
      fprintf(fp, "%g %d moveto\n", x1+i*(x2-x1)/dtick, y1);
      fprintf(fp, "%g %d lineto\n", x1+i*(x2-x1)/dtick, y1+4);
    }
  }
  else if( (label_Ptr->X_Min < 0.0 && 0.0 < label_Ptr->X_Max) ||
	  (label_Ptr->X_Max < 0.0 && 0.0 < label_Ptr->X_Min))
  {
    dtick = (x2-x1)/(label_Ptr->X_Max -label_Ptr->X_Min);
    fprintf(fp, "%g %d moveto\n", x2-dtick*(label_Ptr->X_Max), y2);
    fprintf(fp, "%g %d lineto\n", x2-dtick*(label_Ptr->X_Max), y2-4);
    
    fprintf(fp, "%g %d moveto\n", x2-dtick*(label_Ptr->X_Max), y1);
    fprintf(fp, "%g %d lineto\n", x2-dtick*(label_Ptr->X_Max), y1+4);
  }
  
  /*****************************/
  /* Printing the actual plots */

  if(Is_Y_Log(theOpenDialogBoxWindow))
  {
    my= (y2-y1)/log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
    by= (y1*log10(label_Ptr->Y_Max) -y2*log10(label_Ptr->Y_Min))/log10(label_Ptr->Y_Max/label_Ptr->Y_Min)+0.5;
  }
  else
  {
    my= (y2-y1)/(label_Ptr->Y_Max -label_Ptr->Y_Min +DBL_MIN)*label_Ptr->Y_Scale;
    by= (label_Ptr->Y_Max*y1 - label_Ptr->Y_Min*y2)/(label_Ptr->Y_Max - label_Ptr->Y_Min +DBL_MIN) +0.5;
  }
  if(Is_X_Log(theOpenDialogBoxWindow))
  {
    mx= (x2-x1)/log10(label_Ptr->X_Max/label_Ptr->X_Min);
    bx= (log10(label_Ptr->X_Max)*x1 -log10(label_Ptr->X_Min)*x2)/log10(label_Ptr->X_Max/label_Ptr->X_Min)+0.5;
  }
  else
  {
    mx= (x2-x1)/(label_Ptr->X_Max -label_Ptr->X_Min +DBL_MIN)*label_Ptr->X_Scale;
    bx= (label_Ptr->X_Max*x1 - label_Ptr->X_Min*x2)/(label_Ptr->X_Max - label_Ptr->X_Min +DBL_MIN) +0.5;
  }
  fprintf(fp, "stroke grestore\n\n");
 /* ddd: just agains warnings. Was
  fprintf(fp, "%/boundary {newpath %d %d moveto %d %d lineto\n", x1, y1, x2, y1);
 */
  fprintf(fp, "/boundary {newpath %d %d moveto %d %d lineto\n", x1, y1, x2, y1);
  fprintf(fp, " %d %d lineto %d %d lineto closepath} def\n", x2, y2, x1, y2);
  fprintf(fp, "gsave boundary clip\n");
  
  fprintf(fp, ".25 setlinewidth\n\n");
  for(nplot=0, ptr= data_Ptr; ptr != NULL; ptr= ptr->next) nplot++;
  
  for(ptr= data_Ptr, j=0; ptr != NULL; ptr= ptr->next, j++)
  {
    n = *(ptr->npoints);
    if (!(M_Point= (MeshType *)malloc(n*sizeof(MeshType)))) putchar(7);
    
    if(Is_X_Log(theOpenDialogBoxWindow))
      for (i=0; i<n; i++) M_Point[i].x= mx*log10(label_Ptr->X_Scale*ptr->x[i]+DBL_MIN)+bx;
    else for (i=0; i<n; i++) M_Point[i].x= mx*ptr->x[i]+bx;
    
    if(Is_Y_Log(theOpenDialogBoxWindow))
      for (i=0; i<n; i++) M_Point[i].y= my*log10(label_Ptr->Y_Scale*ptr->y[i]+DBL_MIN)+by;
    else for (i=0; i<n; i++) M_Point[i].y= my*ptr->y[i]+by;
    
    if (Is_Scatter(ptr))
    {
      fprintf(fp, "0 setgray\n");
      fprintf(fp, "/Times-Bold findfont 6 scalefont setfont\n");
      fprintf(fp, "newpath\n");
      for(i=0; i< n; i++)
	if(x1<=M_Point[i].x && M_Point[i].x<=x2 && y1<=M_Point[i].y && M_Point[i].y<=y2) 
	  fprintf(fp, "%g %g moveto sp%d\n", M_Point[i].x, M_Point[i].y, j);
      fprintf(fp, "stroke\n\n");
    }
    else
    {
      fprintf(fp, "%.3G setgray\n", ((float)j)/nplot);
      fprintf(fp, "newpath %g %g moveto\n", M_Point[0].x, M_Point[0].y);
      for (i=1; i< n; i++)
      {
	fprintf(fp, "%g %g lineto\n", M_Point[i].x, M_Point[i].y);
	if(!(i%NPOINTMAX))
	{
	  fprintf(fp, "stroke\n\n");
	  fprintf(fp, "newpath %g %g moveto\n", M_Point[i].x, M_Point[i].y);
	}
      }
      fprintf(fp, "stroke\n\n");
    }
    free(M_Point);
  } 
  fprintf(fp, "grestore\n");
  fprintf(fp, "showpage\n\n");
  if(fclose(fp)) printf("PostScriptOpenWindow(): File was not closed properly!");

  return(1);            /* ddd: just against warnings */
}

/****************************************************************/

void PSHeader()
{
  /*****************************/
  /* Loading the dictionary... */
  
  fprintf(fp, "%%!\n");
 /* ddd: just agains warnings. Was
  fprintf(fp, "%/prtstrfrommidlow {dup stringwidth pop\n");
 */
  fprintf(fp, "/prtstrfrommidlow {dup stringwidth pop\n");
  fprintf(fp, " 2 div currentpoint pop exch sub currentpoint\n");
  fprintf(fp, " exch pop moveto show} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/prtstrfrommidup {dup stringwidth currentpoint\n");
 */
  fprintf(fp, "/prtstrfrommidup {dup stringwidth currentpoint\n");
  fprintf(fp, " 3 -1 roll sub exch 3 -1 roll 2 div sub exch\n");
  fprintf(fp, " moveto show} def\n\n");
  
 /* ddd: just agains warnings. Was
  fprintf(fp, "%/prtstrfromritlow {dup stringwidth pop\n");
 */
  fprintf(fp, "/prtstrfromritlow {dup stringwidth pop\n");
  fprintf(fp, " currentpoint pop exch sub currentpoint\n");
  fprintf(fp, " exch pop moveto show} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/prtstrfromritup {dup stringwidth currentpoint\n");
 */
  fprintf(fp, "/prtstrfromritup {dup stringwidth currentpoint\n");
  fprintf(fp, " 3 -1 roll sub exch 3 -1 roll sub exch\n");
  fprintf(fp, " moveto show} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/prtstrfromlftup {dup stringwidth exch pop\n");
 */
  fprintf(fp, "/prtstrfromlftup {dup stringwidth exch pop\n");
  fprintf(fp, " currentpoint 3 -1 roll sub moveto show} def\n\n");
   
 /* ddd: just agains warnings. Was
  fprintf(fp, "%/rectangle {4 -1 roll 4 -1 roll\n");
 */
  fprintf(fp, "/rectangle {4 -1 roll 4 -1 roll\n");
  fprintf(fp, " dup 5 1 roll exch dup 6 1 roll exch\n");
  fprintf(fp, " moveto 3 1 roll dup 5 1 roll exch lineto dup\n"); 
  fprintf(fp, " 4 -1 roll exch lineto lineto closepath gsave setgray\n");
  fprintf(fp, " fill grestore stroke} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/fbpolygon {newpath moveto lineto\n");
 */
  fprintf(fp, "/fbpolygon {newpath moveto lineto\n");
  fprintf(fp, " lineto lineto closepath gsave setgray\n");
  fprintf(fp, " fill grestore stroke} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/bpolygon {newpath moveto lineto\n");
 */
  fprintf(fp, "/bpolygon {newpath moveto lineto\n");
  fprintf(fp, " lineto lineto closepath stroke} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/fpolygon {newpath moveto lineto\n");
 */
  fprintf(fp, "/fpolygon {newpath moveto lineto\n");
  fprintf(fp, " lineto lineto closepath gsave setgray\n");
  fprintf(fp, " fill grestore} def\n\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/sp0 {(.) prtstrfrommidlow} def\n");
  fprintf(fp, "%/sp1 {(o) prtstrfrommidlow} def\n");
  fprintf(fp, "%/sp2 {-1 -1 rmoveto 0 2 rlineto\n");
 */
  fprintf(fp, "/sp0 {(.) prtstrfrommidlow} def\n");
  fprintf(fp, "/sp1 {(o) prtstrfrommidlow} def\n");
  fprintf(fp, "/sp2 {-1 -1 rmoveto 0 2 rlineto\n");
  fprintf(fp, " 2 0 rlineto 0 -2 rlineto closepath} def\n");

 /* ddd: just agains warnings. Was
  fprintf(fp, "%/sp3 {(*) prtstrfrommidlow} def\n");
  fprintf(fp, "%/sp4 {(x) prtstrfrommidlow} def\n");
  fprintf(fp, "%/sp5 {(+) prtstrfrommidlow} def\n");
  fprintf(fp, "%/sp6 {(@) prtstrfrommidlow} def\n\n");
 */
  fprintf(fp, "/sp3 {(*) prtstrfrommidlow} def\n");
  fprintf(fp, "/sp4 {(x) prtstrfrommidlow} def\n");
  fprintf(fp, "/sp5 {(+) prtstrfrommidlow} def\n");
  fprintf(fp, "/sp6 {(@) prtstrfrommidlow} def\n\n");
}

/****************************************************************/

int PostScript_ThreeD_Window()
{
  DataType   data_Ptr;    
  LabelType  label_Ptr;
  MeshType **theMeshPoint, theBox[8];
  StringType theString[8];

  float n1, n2, n3, v1, v2, v3;
  float u1, u2, u3, up1, up2, up3;
  float a1, a2, a3, b1, b2, b3;
  float xprojmax, xprojmin, color;
  float yprojmax, yprojmin; 
  float mag, c1, c2, d1, d2;
  float xtemp, ytemp, ztemp;

  int   m, mstart, mend, n, nend, nstart;
  int   i, j, x1, y1, x2, y2;
  int   phi_flag, theta_flag; 
  int   xstart, xend, xstep, ystart, yend, ystep;

  data_Ptr = theOpenDialogBoxWindow->data;
  label_Ptr= theOpenDialogBoxWindow->label;

  /**************************************************/
  /* Determining the number of items in the x_array */

  if(!Is_Scatter(data_Ptr))
  {
    m= *(data_Ptr->mpoints);
    mstart = m*(label_Ptr->X_Min/label_Ptr->X_Scale - data_Ptr->x[0])/(data_Ptr->x[m-1] -data_Ptr->x[0]) +.5;
    if(mstart <0) mstart=0;  else if(mstart >m) mstart=m;
    mend   = m*(label_Ptr->X_Max/label_Ptr->X_Scale - data_Ptr->x[0])/(data_Ptr->x[m-1] -data_Ptr->x[0]);
    if(mend <0)   mend=0;    else if(mend >m) mend=m;
  }
  /**************************************************/
  /* Determining the number of items in the y_array */

  n= *(data_Ptr->npoints);
  if(!Is_Scatter(data_Ptr))
  {
    nstart = n*(label_Ptr->Y_Min/label_Ptr->Y_Scale - data_Ptr->y[0])/(data_Ptr->y[n-1] -data_Ptr->y[0]) +.5;
    if(nstart <0) nstart=0;  else if(nstart >n) nstart=n;
    nend   = n*(label_Ptr->Y_Max/label_Ptr->Y_Scale - data_Ptr->y[0])/(data_Ptr->y[n-1] -data_Ptr->y[0]);
    if(nend <0)   nend=0;    else if(nend >n) nend=n;
  }

  /******************************************************/ 
  /* Determining the octant where the viewer is located */

  theOpenDialogBoxWindow->theta= fmod(180.+theOpenDialogBoxWindow->theta, 180.);
  theOpenDialogBoxWindow->phi  = fmod(360.+theOpenDialogBoxWindow->phi, 360.);
  
  if(0 <= theOpenDialogBoxWindow->phi && theOpenDialogBoxWindow->phi <= 90)        phi_flag = FIRST_QUAD;
  else if(90 < theOpenDialogBoxWindow->phi && theOpenDialogBoxWindow->phi <= 180)  phi_flag = SECOND_QUAD;
  else if(180 < theOpenDialogBoxWindow->phi && theOpenDialogBoxWindow->phi <= 270) phi_flag = THIRD_QUAD;
  else if(270 < theOpenDialogBoxWindow->phi && theOpenDialogBoxWindow->phi <= 360) phi_flag = FOURTH_QUAD;
  
  if(theOpenDialogBoxWindow->theta == 0.0)                                          theta_flag = ABOVE;
  else if(0 < theOpenDialogBoxWindow->theta && theOpenDialogBoxWindow->theta <= 90) theta_flag = UPPER;
  else                                                                              theta_flag = LOWER;
  
  /************************************/ 
  /* Calculating the rotation vectors */

  n1= sin(theOpenDialogBoxWindow->theta*M_PI/180.)*cos(theOpenDialogBoxWindow->phi*M_PI/180.);
  n2= sin(theOpenDialogBoxWindow->theta*M_PI/180.)*sin(theOpenDialogBoxWindow->phi*M_PI/180.);
  n3= cos(theOpenDialogBoxWindow->theta*M_PI/180.);
  
  if(theta_flag == ABOVE){ up1= 0;  up2= 1;  up3= 0; }
  else                   { up1= 0;  up2= 0;  up3= 1; }
  
  u1  = up2*n3 -up3*n2;
  u2  = up3*n1 -up1*n3;
  u3  = up1*n2 -up2*n1;
  mag = sqrt(u1*u1 + u2*u2 + u3*u3);
  
  u1 /= mag;
  u2 /= mag;
  u3 /= mag;
  
  v1  = n2*u3 -n3*u2;
  v2  = n3*u1 -n1*u3;
  v3  = n1*u2 -n2*u1;
  
  /***********************************************************/
  /* Calculating the bounding box and the projection scaling */
  
  theBox[0].x = 0;       theBox[1].x = u1;  theBox[2].x = u1 +u2;  theBox[3].x = u2;
  theBox[0].y = 0;       theBox[1].y = v1;  theBox[2].y = v1 +v2;  theBox[3].y = v2;
  
  theBox[4].x = u2 +u3;  theBox[5].x = u3;  theBox[6].x = u1 +u3;  theBox[7].x = u1 +u2 +u3;
  theBox[4].y = v2 +v3;  theBox[5].y = v3;  theBox[6].y = v1 +v3;  theBox[7].y = v1 +v2 +v3;
  
  xprojmin = xprojmax = theBox[0].x;
  yprojmin = yprojmax = theBox[0].y;
  for(i = 1; i < 8; i++)
  {
    xprojmin = (xprojmin < theBox[i].x) ? xprojmin : theBox[i].x;
    xprojmax = (xprojmax > theBox[i].x) ? xprojmax : theBox[i].x;
    yprojmin = (yprojmin < theBox[i].y) ? yprojmin : theBox[i].y;
    yprojmax = (yprojmax > theBox[i].y) ? yprojmax : theBox[i].y;
  }
  
  /********************************************************************/
  /* selecting the labels to print based on the given point of view   */

  if(theta_flag != ABOVE)
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Min); theString[0].x = u1;       theString[0].y = v1;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = u1+.5*u2; theString[1].y = v1+.5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Max); theString[2].x = u1+u2;    theString[2].y = v1+v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Max); theString[3].x = u1+u2;    theString[3].y = v1+v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1+u2; theString[4].y = .5*v1+v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Min); theString[5].x = u2;       theString[5].y = v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u2;       theString[6].y = v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u2+u3;    theString[7].y = v2+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Max); theString[0].x = u1;       theString[0].y = v1;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1;    theString[1].y = .5*v1;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Min); theString[2].x = 0.0;      theString[2].y = 0.0;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Min); theString[3].x = 0.0;      theString[3].y = 0.0;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = .5*u2;    theString[4].y = .5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Max); theString[5].x = u2;       theString[5].y = v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u2;       theString[6].y = v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u2+u3;    theString[7].y = v2+v3;
	}
	break;
	
      case SECOND_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Max); theString[0].x = u1+u2;    theString[0].y = v1+v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1+u2; theString[1].y = .5*v1+v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Min); theString[2].x = u2;       theString[2].y = v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Max); theString[3].x = u2;       theString[3].y = v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = .5*u2;    theString[4].y = .5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Min); theString[5].x = 0.0;      theString[5].y = 0.0;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = 0.0;      theString[6].y = 0.0;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u3;       theString[7].y = v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Max); theString[0].x = u1+ u2;   theString[0].y = v1+v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = u1+.5*u2; theString[1].y = v1+.5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Min); theString[2].x = u1;       theString[2].y = v1;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Max); theString[3].x = u1;       theString[3].y = v1;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1;    theString[4].y = .5*v1;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Min); theString[5].x = 0.0;      theString[5].y = 0.0;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = 0.0;      theString[6].y = 0.0;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u3;       theString[7].y = v3;
	}
	break;
	
      case THIRD_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Max); theString[0].x = u2;       theString[0].y = v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = .5*u2;    theString[1].y = .5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Min); theString[2].x = 0.0;      theString[2].y = 0.0;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Min); theString[3].x = 0.0;      theString[3].y = 0.0;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1;    theString[4].y = .5*v1;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Max); theString[5].x = u1;       theString[5].y = v1;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1;       theString[6].y = v1;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u3;    theString[7].y = v1+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Min); theString[0].x = u2;       theString[0].y = v2;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1+u2; theString[1].y = .5*v1+v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Max); theString[2].x = u1+u2;    theString[2].y = v1+v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Max); theString[3].x = u1+u2;    theString[3].y = v1+v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = u1+.5*u2; theString[4].y = v1+.5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Min); theString[5].x = u1;       theString[5].y = v1;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1;       theString[6].y = v1;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u3;    theString[7].y = v1+v3;
	}
	break;
	
      case FOURTH_QUAD:
	if(theta_flag == UPPER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->X_Min); theString[0].x = 0.0;      theString[0].y = 0.0;
	  sprintf(theString[1].buffer, "%s", label_Ptr->X_Label); theString[1].x = .5*u1;    theString[1].y = .5*v1;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->X_Max); theString[2].x = u1;       theString[2].y = v1;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->Y_Min); theString[3].x = u1;       theString[3].y = v1;
	  sprintf(theString[4].buffer, "%s", label_Ptr->Y_Label); theString[4].x = u1+.5*u2; theString[4].y = v1+.5*v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->Y_Max); theString[5].x = u1+u2;    theString[5].y = v1+v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1+u2;    theString[6].y = v1+v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u2+u3; theString[7].y = v1+v2+v3;
	}
	else if(theta_flag == LOWER)
	{
	  sprintf(theString[0].buffer, "%.4G", label_Ptr->Y_Min); theString[0].x = 0.0;      theString[0].y = 0.0;
	  sprintf(theString[1].buffer, "%s", label_Ptr->Y_Label); theString[1].x = .5*u2;    theString[1].y = .5*v2;
	  sprintf(theString[2].buffer, "%.4G", label_Ptr->Y_Max); theString[2].x = u2;       theString[2].y = v2;
	  sprintf(theString[3].buffer, "%.4G", label_Ptr->X_Min); theString[3].x = u2;       theString[3].y = v2;
	  sprintf(theString[4].buffer, "%s", label_Ptr->X_Label); theString[4].x = .5*u1+u2; theString[4].y = .5*v1+v2;
	  sprintf(theString[5].buffer, "%.4G", label_Ptr->X_Max); theString[5].x = u1+u2;    theString[5].y = v1+v2;
	  sprintf(theString[6].buffer, "%.4G", label_Ptr->Z_Min); theString[6].x = u1+u2;    theString[6].y = v1+v2;
	  sprintf(theString[7].buffer, "%.4G", label_Ptr->Z_Max); theString[7].x = u1+u2+u3; theString[7].y = v1+v2+v3;
	}
	break;
      }
  }
  
  /**************************************************/
  
  if (label_Ptr->Z_Max == label_Ptr->Z_Min || label_Ptr->Y_Max == label_Ptr->Y_Min ||
      label_Ptr->X_Max == label_Ptr->X_Min) return(1);
				/* ddd: return(1) - just to return */
  
  /****************************************************/
  /*  Initialize the PS file and load the dictionary  */

  if(!(fp= fopen(theOpenDialogBoxWindow->ps_file_name, "w")))
  {
    printf("PostScriptOpenWindow(): File was not opened properly!");
    return(1);            /* ddd: return(1) - just against warnings */
  }
  PSHeader();

  /************************************************/
  /*  Rotate, translate, and draw the boundaries */

  fprintf(fp, "1 setlinejoin\n");
  fprintf(fp, "612 0 translate\n");
  fprintf(fp, "90 rotate\n");
  fprintf(fp, "1 setlinewidth\n");
  fprintf(fp, "0 setgray\n");
  
  x1 = 108;     x2 = 684;
  y1 = 108;     y2 = 504;
  
  c1 = (x2-x1)/(xprojmax -xprojmin +DBL_MIN);
  d1 = (xprojmax*x1 - xprojmin*x2)/(xprojmax - xprojmin + DBL_MIN) + 0.5;
  c2 = (y2-y1)/(yprojmax -yprojmin +DBL_MIN);
  d2 = (yprojmax*y1 - yprojmin*y2)/(yprojmax - yprojmin + DBL_MIN) + 0.5;

  if(theta_flag != ABOVE)
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 0, BACK);
        else
          PaintWall(theBox, c1, d1, c2, d2, 5, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 1, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 4, BACK);
        break;

      case SECOND_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 0, BACK);
        else
          PaintWall(theBox, c1, d1, c2, d2, 5, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 1, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 2, BACK);
        break;

      case THIRD_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 0, BACK);
        else
          PaintWall(theBox, c1, d1, c2, d2, 5, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 2, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 3, BACK);
        break;

      case FOURTH_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 0, BACK);
        else
          PaintWall(theBox, c1, d1, c2, d2, 5, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 3, BACK);
        PaintWall(theBox, c1, d1, c2, d2, 4, BACK);
        break;
      }
  }

  /*******************************/
  /* painting the labels         */

  fprintf(fp, "\n/Times-BoldItalic findfont 14 scalefont setfont\n");
  fprintf(fp, "396 550 moveto\n");
  fprintf(fp, "(%s) prtstrfrommidlow\n", theOpenDialogBoxWindow->plot_title);

  fprintf(fp, "\n/Times-BoldItalic findfont 12 scalefont setfont\n");
  fprintf(fp, "396 512 moveto\n");
  fprintf(fp, "(%s) prtstrfrommidlow\n", label_Ptr->Z_Label);
  
  if(theta_flag == ABOVE)
  {
    fprintf(fp, "90 rotate\n");
    fprintf(fp, "306 -100 moveto\n");
    fprintf(fp, "(%s) prtstrfrommidlow\n", label_Ptr->Y_Label);
    fprintf(fp, "-90 rotate\n");
    
    fprintf(fp, "396 92 moveto\n");
    fprintf(fp, "(%s) prtstrfrommidup\n", label_Ptr->X_Label);
    
    fprintf(fp, "/Times-Bold findfont 12 scalefont setfont\n");
    fprintf(fp, "108 92 moveto\n");
    fprintf(fp, "(%.3G) prtstrfromlftup\n", label_Ptr->X_Min);
    fprintf(fp, "684 92 moveto\n");
    fprintf(fp, "(%.3G) prtstrfromritup\n", label_Ptr->X_Max);

    fprintf(fp, "100 495 moveto\n");
    fprintf(fp, "(%.3G) prtstrfromritup\n", label_Ptr->Y_Max);
    fprintf(fp, "100 108 moveto\n");
    fprintf(fp, "(%.3G) show\n", label_Ptr->Y_Min);
    fprintf(fp, "1 %d %d %d %d rectangle\n", x1, y1, x2, y2);
  }
  else
  {
    fprintf(fp, "%d %d moveto\n", (int)(c1*theString[1].x+d1-15), (int)(c2*theString[1].y+d2-15));
    fprintf(fp, "(%s) prtstrfromritup\n", theString[1].buffer);

    fprintf(fp, "%d %d moveto\n", (int)(c1*theString[4].x+d1+15), (int)(c2*theString[4].y+d2-15));
    fprintf(fp, "(%s) prtstrfromlftup\n", theString[4].buffer);

    fprintf(fp, "/Times-Bold findfont 12 scalefont setfont\n");
    fprintf(fp, "%d %d moveto\n", x1, (int)(c2*theString[0].y+d2-15));
    fprintf(fp, "(%s) prtstrfromritup\n", theString[0].buffer);

    fprintf(fp, "%d %d moveto\n", (int)(c1*theString[2].x+d1-15), y1-15);
    fprintf(fp, "(%s) prtstrfromritup\n", theString[2].buffer);

    fprintf(fp, "%d %d moveto\n", (int)(c1*theString[3].x+d1+15), y1-15);
    fprintf(fp, "(%s) prtstrfromlftup\n", theString[3].buffer);

    fprintf(fp, "%d %d moveto\n", x2, (int)(c2*theString[5].y+d2-15));
    fprintf(fp, "(%s) prtstrfromlftup\n", theString[5].buffer);

    fprintf(fp, "%d %d moveto\n", x2+5, (int)(c2*theString[6].y+d2+5));
    fprintf(fp, "(%s) show\n", theString[6].buffer);

    fprintf(fp, "%d %d moveto\n", x2+5, (int)(c2*theString[7].y+d2));
    fprintf(fp, "(%s) prtstrfromlftup\n", theString[7].buffer);
  }

  /***********************************************/
  /* Used for scaling the arrays before rotating */

  if(Is_X_Log(theOpenDialogBoxWindow))
  {
    a1 = 1.0/log10(label_Ptr->X_Max/label_Ptr->X_Min);
    b1 = log10(label_Ptr->X_Min/label_Ptr->X_Scale)/log10(label_Ptr->X_Max/label_Ptr->X_Min);
  }
  else
  {
    a1 = label_Ptr->X_Scale/(label_Ptr->X_Max - label_Ptr->X_Min);
    b1 = label_Ptr->X_Min/(label_Ptr->X_Max - label_Ptr->X_Min);
  }
  if(Is_Y_Log(theOpenDialogBoxWindow))
  {
    a2 = 1.0/log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
    b2 = log10(label_Ptr->Y_Min/label_Ptr->Y_Scale)/log10(label_Ptr->Y_Max/label_Ptr->Y_Min);
  }
  else
  {
    a2 = label_Ptr->Y_Scale/(label_Ptr->Y_Max - label_Ptr->Y_Min);
    b2 = label_Ptr->Y_Min/(label_Ptr->Y_Max - label_Ptr->Y_Min);
  }
  if(Is_Z_Log(theOpenDialogBoxWindow))
  {
    a3 = 1.0/log10(label_Ptr->Z_Max/label_Ptr->Z_Min);
    b3 = log10(label_Ptr->Z_Min/label_Ptr->Z_Scale)/log10(label_Ptr->Z_Max/label_Ptr->Z_Min);
  }
  else
  {
    a3 = label_Ptr->Z_Scale/(label_Ptr->Z_Max - label_Ptr->Z_Min);
    b3 = label_Ptr->Z_Min/(label_Ptr->Z_Max - label_Ptr->Z_Min);
  }
  
  /********************************************/
  /* do the actual 3d drawing onto the pixmap */

  if(Is_Scatter(data_Ptr))
  {
    fprintf(fp, "0 setgray\n");
    fprintf(fp, "/Times-Bold findfont 6 scalefont setfont\n");
    fprintf(fp, "newpath\n");
    for(i = 0; i< n; i++)
    {
      if(Is_X_Log(theOpenDialogBoxWindow)) xtemp = a1*log10(data_Ptr->x[i])-b1;
      else                                xtemp = a1*data_Ptr->x[i] -b1;
      if(Is_Y_Log(theOpenDialogBoxWindow)) ytemp = a2*log10(data_Ptr->y[i])-b2;
      else                                ytemp = a2*data_Ptr->y[i] -b2;
      if(Is_Z_Log(theOpenDialogBoxWindow)) ztemp = a3*log10(data_Ptr->zscat[i]) -b3;
      else                                ztemp = a3*data_Ptr->zscat[i] -b3;
      if(0.0<xtemp && xtemp<1.0 && 0.0<ytemp && ytemp<1.0 && 0.0<ztemp && ztemp<1.0)
	fprintf(fp, "%g %g moveto sp0\n", c1*(u1*xtemp +u2*ytemp +u3*ztemp)+d1,
		c2*(v1*xtemp +v2*ytemp +v3*ztemp)+d2);
    }
    fprintf(fp, "stroke\n\n");
  }
  else
  {
    theMeshPoint = (MeshType **)malloc(m*sizeof(MeshType *));
    for(i = 0; i < m; i++)
    {
      theMeshPoint[i] = (MeshType *)malloc(n*sizeof(MeshType));
      for(j = 0; j < n; j++)
      {
	if(Is_X_Log(theOpenDialogBoxWindow)) xtemp = a1*log10(data_Ptr->x[i])-b1;
	else                    xtemp = a1*data_Ptr->x[i] -b1;
	if(Is_Y_Log(theOpenDialogBoxWindow)) ytemp = a2*log10(data_Ptr->y[j])-b2;
	else                    ytemp = a2*data_Ptr->y[j] -b2;
	if(Is_Z_Log(theOpenDialogBoxWindow)) ztemp = a3*log10(data_Ptr->z[i][j]) -b3;
	else                    ztemp = a3*data_Ptr->z[i][j] -b3;
	if(ztemp >1.0) ztemp = 1.0; else if(ztemp<0.0) ztemp = 0.0;
	theMeshPoint[i][j].x = u1*xtemp +u2*ytemp +u3*ztemp;
	theMeshPoint[i][j].y = v1*xtemp +v2*ytemp +v3*ztemp;
      }
    }
    
    /*********************************/
    
    switch (phi_flag)
      {
      case FIRST_QUAD:
	xstart = mstart; xend= mend-1; xstep = 1; ystart = nstart; yend= nend-1; ystep = 1;
	break;
	
      case SECOND_QUAD:
	xstart = mend-2; xend= mstart-1; xstep = -1; ystart = nstart; yend= nend-1; ystep = 1;
	break;
	
      case THIRD_QUAD:
	xstart = mend-2; xend= mstart-1; xstep = -1; ystart = nend-2; yend= nstart-1; ystep = -1;
	break;
	
      case FOURTH_QUAD:
	xstart = mstart; xend= mend-1; xstep = 1; ystart = nend-2; yend= nstart-1; ystep = -1;
	break;
      }
    
    if(Is_Shading_On(theOpenDialogBoxWindow)) color = .75;
    else                                      color = 1;
    
    if(Is_Shading_On(theOpenDialogBoxWindow) || Is_Grid_On(theOpenDialogBoxWindow))
    {
      fprintf(fp, "\n.4 setlinewidth\n");
      for(i = xstart; i != xend; i +=xstep)
	for(j = ystart; j != yend; j +=ystep)
	{
	  if(Is_ColorCode_On(theOpenDialogBoxWindow))
	  {
	    if(Is_Z_Log(theOpenDialogBoxWindow))
              color = 1 -0.9*(.25*a3*log10(data_Ptr->z[i][j]*data_Ptr->z[i+1][j]
					   *data_Ptr->z[i+1][j+1]*data_Ptr->z[i][j+1]) -b3);
            else
              color = 1 -0.9*(.25*a3*(data_Ptr->z[i][j] +data_Ptr->z[i+1][j]
				      +data_Ptr->z[i+1][j+1]+data_Ptr->z[i][j+1]) -b3);
	    if(color > 1) color = 1;
	    else if(color < 0.1) color = 0.1;
	  }
	  if(Is_Grid_On(theOpenDialogBoxWindow))
	    fprintf(fp, "%.3g %d %d %d %d %d %d %d %d fbpolygon\n", color, 
		    (int)(c1*theMeshPoint[i][j].x +d1),     (int)(c2*theMeshPoint[i][j].y +d2),
		    (int)(c1*theMeshPoint[i+1][j].x +d1),   (int)(c2*theMeshPoint[i+1][j].y +d2),
		    (int)(c1*theMeshPoint[i+1][j+1].x +d1), (int)(c2*theMeshPoint[i+1][j+1].y +d2),
		    (int)(c1*theMeshPoint[i][j+1].x +d1),   (int)(c2*theMeshPoint[i][j+1].y +d2));
	  else
	    fprintf(fp, "%.3g %d %d %d %d %d %d %d %d fpolygon\n", color, 
		    (int)(c1*theMeshPoint[i][j].x +d1),     (int)(c2*theMeshPoint[i][j].y +d2),
		    (int)(c1*theMeshPoint[i+1][j].x +d1),   (int)(c2*theMeshPoint[i+1][j].y +d2),
		    (int)(c1*theMeshPoint[i+1][j+1].x +d1), (int)(c2*theMeshPoint[i+1][j+1].y +d2),
		    (int)(c1*theMeshPoint[i][j+1].x +d1),   (int)(c2*theMeshPoint[i][j+1].y +d2));
	}
    }
    /*********************************************************/
    /* Free up the memory for the memory for the mesh points */
    
    for(i = 0; i < m; i++) free(theMeshPoint[i]);
    free(theMeshPoint);
  }
  /***********************/
  /* Draw the front walls */
  
  fprintf(fp, "\n1 setlinewidth\n");
  fprintf(fp, "0 setgray\n");
  
  if(theta_flag != ABOVE)
  {
    switch (phi_flag)
      {
      case FIRST_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 5, FRONT);
        else
          PaintWall(theBox, c1, d1, c2, d2, 0, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 2, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 3, FRONT);
        break;

      case SECOND_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 5, FRONT);
        else
          PaintWall(theBox, c1, d1, c2, d2, 0, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 3, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 4, FRONT);
        break;

      case THIRD_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 5, FRONT);
        else
          PaintWall(theBox, c1, d1, c2, d2, 0, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 1, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 4, FRONT);
        break;

      case FOURTH_QUAD:
        if(theta_flag == UPPER)
          PaintWall(theBox, c1, d1, c2, d2, 5, FRONT);
        else
          PaintWall(theBox, c1, d1, c2, d2, 0, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 1, FRONT);
        PaintWall(theBox, c1, d1, c2, d2, 2, FRONT);
        break;
      }
  }
  /*********************************************************/
  fprintf(fp, "\ngrestore\n");
  fprintf(fp, "showpage\n\n");
  if(fclose(fp)) printf("PostScriptOpenWindow(): File was not closed properly!");

  return(1);     /* ddd: return(1) - just to return */
}

/****************************************************************/

void PaintWall(MeshType *theBox, float c1, float d1, float c2, 
	float d2, int wall, int side)
{
  XPoint thePoint[4];

  if(wall == 0)
  {
    thePoint[0].x= c1*theBox[0].x+d1;  thePoint[0].y= c2*theBox[0].y+d2;
    thePoint[1].x= c1*theBox[1].x+d1;  thePoint[1].y= c2*theBox[1].y+d2;
    thePoint[2].x= c1*theBox[2].x+d1;  thePoint[2].y= c2*theBox[2].y+d2;
    thePoint[3].x= c1*theBox[3].x+d1;  thePoint[3].y= c2*theBox[3].y+d2;
  }
  else if(wall == 1)
  {
    thePoint[0].x= c1*theBox[0].x+d1;  thePoint[0].y= c2*theBox[0].y+d2;
    thePoint[1].x= c1*theBox[1].x+d1;  thePoint[1].y= c2*theBox[1].y+d2;
    thePoint[2].x= c1*theBox[6].x+d1;  thePoint[2].y= c2*theBox[6].y+d2;
    thePoint[3].x= c1*theBox[5].x+d1;  thePoint[3].y= c2*theBox[5].y+d2;
  }
  else if(wall == 2)
  {
    thePoint[0].x= c1*theBox[1].x+d1;  thePoint[0].y= c2*theBox[1].y+d2;
    thePoint[1].x= c1*theBox[2].x+d1;  thePoint[1].y= c2*theBox[2].y+d2;
    thePoint[2].x= c1*theBox[7].x+d1;  thePoint[2].y= c2*theBox[7].y+d2;
    thePoint[3].x= c1*theBox[6].x+d1;  thePoint[3].y= c2*theBox[6].y+d2;
  }
  else if(wall == 3)
  {
    thePoint[0].x= c1*theBox[2].x+d1;  thePoint[0].y= c2*theBox[2].y+d2;
    thePoint[1].x= c1*theBox[3].x+d1;  thePoint[1].y= c2*theBox[3].y+d2;
    thePoint[2].x= c1*theBox[4].x+d1;  thePoint[2].y= c2*theBox[4].y+d2;
    thePoint[3].x= c1*theBox[7].x+d1;  thePoint[3].y= c2*theBox[7].y+d2;
  }
  else if(wall == 4)
  {
    thePoint[0].x= c1*theBox[3].x+d1;  thePoint[0].y= c2*theBox[3].y+d2;
    thePoint[1].x= c1*theBox[0].x+d1;  thePoint[1].y= c2*theBox[0].y+d2;
    thePoint[2].x= c1*theBox[5].x+d1;  thePoint[2].y= c2*theBox[5].y+d2;
    thePoint[3].x= c1*theBox[4].x+d1;  thePoint[3].y= c2*theBox[4].y+d2;
  }
  else if(wall == 5)
  {
    thePoint[0].x= c1*theBox[4].x+d1;  thePoint[0].y= c2*theBox[4].y+d2;
    thePoint[1].x= c1*theBox[5].x+d1;  thePoint[1].y= c2*theBox[5].y+d2;
    thePoint[2].x= c1*theBox[6].x+d1;  thePoint[2].y= c2*theBox[6].y+d2;
    thePoint[3].x= c1*theBox[7].x+d1;  thePoint[3].y= c2*theBox[7].y+d2;
  }

  if(side == BACK)
    fprintf(fp, "1 %d %d %d %d %d %d %d %d fbpolygon\n", 
	    thePoint[0].x, thePoint[0].y, thePoint[1].x, thePoint[1].y,
	    thePoint[2].x, thePoint[2].y, thePoint[3].x, thePoint[3].y);
  else 
    fprintf(fp, "%d %d %d %d %d %d %d %d bpolygon\n", 
	    thePoint[0].x, thePoint[0].y, thePoint[1].x, thePoint[1].y,
	    thePoint[2].x, thePoint[2].y, thePoint[3].x, thePoint[3].y);
}

/****************************************************************/

void XGRead(void *ptr, int size, int nitems, FILE *stream, char *type) /* ddd*/
{
#ifdef IBM
  sun_read(ptr, size, nitems, stream);
#endif

#ifdef DEC
  fread(ptr, size, nitems, stream);
#endif

#ifdef SUN
  sun_read(ptr, size, nitems, stream);
#endif

#ifdef HP
  sun_read(ptr, size, nitems, stream);
#endif

#ifdef UNICOS
  if(!strcmp(type, "float"))     unicos_read_float(ptr, nitems, stream);
  else if(!strcmp(type, "int"))  unicos_read_int(ptr, nitems, stream);
  else if(!strcmp(type, "char")) fread(ptr, size, nitems, stream);
  else                           puts("XGRead: unrecognized type");
#endif
}

/******************************************************/

void XGWrite(void *ptr, int size, int nitems, FILE *stream, char *type) /* ddd*/
{
#ifdef IBM
  sun_write(ptr, size, nitems, stream);
#endif
  
#ifdef DEC
  fwrite(ptr, size, nitems, stream);
#endif
  
#ifdef SUN
  sun_write(ptr, size, nitems, stream);
#endif
  
#ifdef HP
  sun_write(ptr, size, nitems, stream);
#endif

#ifdef UNICOS
  if(!strcmp(type, "float"))     unicos_write_float(ptr, nitems, stream);
  else if(!strcmp(type, "int"))  unicos_write_int(ptr, nitems, stream);
  else if(!strcmp(type, "char")) fwrite(ptr, size, nitems, stream); 
  else                           puts("XGWrite: unrecognized type");
#endif
}

/******************************************************/

void sun_read(char *ptr, int size, int nitems, FILE *stream) /* ddd */
{
  int i, j;
  
  for(j= 0; j <nitems; j++)
    for(i= size-1; i >=0; i--)
      fread(ptr+j*size+i, 1, 1, stream);
}

/******************************************************/

void sun_write(char *ptr, int size, int nitems, FILE *stream) /* ddd */
{
  int i, j;
  
  for(j= 0; j <nitems; j++)
    for(i= size-1; i >=0; i--)
      fwrite(ptr+j*size+i, 1, 1, stream);
}

/******************************************************/

#ifdef UNICOS
void unicos_read_float(float *ptr, int nitems, FILE *stream) /* ddd */
{
  unsigned long *iptr;
  unsigned char a,b,c,d,t;
  int j;

  for(j= 0; j <nitems; j++)
  {
    iptr = (unsigned long *)(ptr +j);
    
    fread(&d,1,1,stream);
    fread(&c,1,1,stream);
    fread(&b,1,1,stream);
    fread(&a,1,1,stream);

    if( a == 0 && b == 0 && c == 0 && d == 0) *iptr = 0;
    else 
    {
      t = ((a << 1) | (b >> 7));
      *iptr = ((a  >> 7) << 63) | ((t -126 + 040000) << 48);
      *iptr |= (b | 0x80) << 40;  
      *iptr |= c << 32;
      *iptr |= d << 24;
    }
  }
}
#endif

/******************************************************/

#ifdef UNICOS
void unicos_read_int(int *ptr, int nitems, FILE *stream)   /* ddd */
{
  unsigned long *iptr;
  unsigned char a,b,c,d,t;
  int j;

  for(j= 0; j <nitems; j++)
  {
    iptr = (unsigned long *)(ptr +j);
    
    fread(&a,1,1,stream);
    fread(&b,1,1,stream);
    fread(&c,1,1,stream);
    fread(&d,1,1,stream);

    *iptr = d << 24 | c << 16 | b << 8 | a;
    *iptr |= (d >> 7) ? 0xffffffff00000000 : 0x0;
  }
}
#endif

/******************************************************/

#ifdef UNICOS
void unicos_write_float(float *ptr, int nitems, FILE *stream)   /* ddd */
{
  unsigned long *iptr;
  unsigned char a,b,c,d,t;
  int j;
  
  for(j= 0; j <nitems; j++)
  {
    iptr = (unsigned long *)(ptr +j);

    t = ((*iptr >> 48) & 0xff) - 040000 + 126;
    
    a = ((*iptr & (1 << 63)) ? 1 << 7 : 0) | t >> 1; 
    b = (t & 0x1) << 7 | ((*iptr >> 40) & 0x7f);
    c = *iptr >> 32;
    d = *iptr >> 24;
    
    fwrite(&d,1,1,stream);
    fwrite(&c,1,1,stream);
    fwrite(&b,1,1,stream);
    fwrite(&a,1,1,stream);
  }
}
#endif

/******************************************************/

#ifdef UNICOS
void unicos_write_int(int *ptr, int nitems, FILE *stream)   /* ddd */
{
  unsigned long *iptr;
  unsigned char a,b,c,d,t;
  int j;
  
  for(j= 0; j <nitems; j++)
  {
    iptr = (unsigned long *)(ptr +j);
    
    a = *iptr & 0xff;
    b = *iptr >> 8 & 0xff;
    c = *iptr >> 16 & 0xff;
    d = *iptr >> 24 & 0xff;
    fwrite(&a,1,1,stream);
    fwrite(&b,1,1,stream);
    fwrite(&c,1,1,stream);
    fwrite(&d,1,1,stream);
  }
}
#endif

/****************************************************************/
