/*
*/
/* File 'calcompx.c' performs partial CalComp to Xlib interface.             */
/*                                                                           */
/* This file contains the CalComp plotting routines                          */
/*     PLOTS, PLOT, NEWPEN                                                   */
/*     PLOTS                                           */
/*     PLOT                                            */
/*     NEWPEN                                          */
/* coded in the language C ANSI 9899-1990 standard employing the Xlib        */
/* graphical functions.                                                      */
/*                                                                           */
/* For CalComp specification of the used graphics subroutines in Fortran     */
/* language see: CalComp .           */
/*                                                                           */
/* ver. 5.40                                                                 */
/* date: 2000, March 2                                                       */
/* coded by Vaclav Bucha                                                     */
/*                                                                           */
/* ========================================================================= */
/*                                                                           */
/* Preprocessor control lines:                                               */
/*                                                                           */
/* Include files:                                                            */
#  include 
#  include 
#  include 
/*                                                                           */
/* Window size and position constants:                                       */
/* Important: minimum and maximum size of the window has to be the same.     */
#  define WIN_MIN_WIDTH  650
#  define WIN_MAX_WIDTH  650
#  define WIN_MIN_HEIGHT 650
#  define WIN_MAX_HEIGHT 650
#  define WIN_MOVE_X     300
#  define WIN_MOVE_Y     20
/*                                                                           */
/* WIN_MIN_WIDTH, WIN_MAX_WIDTH...Minimum and maximum width of the window.   */
/* WIN_MIN_HEIGHT, WIN_MAX_HEIGHT...Minimum and maximum height of the window.*/
/* WIN_MOVE_X, WIN_MOVE_Y... x and y coordinates of the upper-left pixel of  */
/*                           the window's border, relative to the window's   */
/*                           parent.                                         */
/*                                                                           */
/*    Dimensions of the plot area (metric A4: 29.7*21.0):                    */
/* #  define XMIN   7.45  */
/* #  define XMAX  29.66  */
/* #  define YMIN   0.00  */
/* #  define YMAX  21.00  */
/*                                                                           */
/* Dimensions of the plot area (US: 11.0*8.5):                               */
#  define XMIN   2.75
#  define XMAX  11.00
#  define YMIN   0.00
#  define YMAX   8.50
/*                                                                           */
/* XMIN, XMAX, YMIN, YMAX...Horizontal and vertical dimensions of the plot   */
/*                          area.                                            */
/*                                                                           */
/* Global (static) variables:                                                */
   char          win_name1[16]="CRT window ", win_name2[16];
   int           iwave=1, kolor, kolrep, icount, mcount=1024;
   unsigned long color[16];
   float         startx, starty, oldx, oldy;

   Colormap      colormap;
   Display       *display;
   GC            gc;
   Window        window;
   XPoint        ln_points[1024];
/*                                                                           */
/* win_name1, win_name2...Strings for window name.                           */
/* iwave...  Contains index of wave.                                         */
/* kolor, kolrep... Contain color index and number for color repetition.     */
/* icount... Number of points for plotting.                                  */
/* mcount... Maximum number of points in array ln_points.                    */
/* color...  Array for color indices.                                        */
/* startx, starty, oldx, oldy... Variables for point coordinates.            */
/* colormap... Contains colormap ID on the specified screen.                 */
/* display...Specifies a connection to an X server.                          */
/* gc...     Graphics context contains values of graphics primitives.        */
/* window... Specifies a window ID.                                          */
/* ln_points...Array with point coordinates.                                 */
/*                                                                           */
/* ========================================================================  */
/*                                                                           */
/* Initialize the Xlib                                                       */
/*                                                                           */
/*                                                       */
/*                                                                           */
#  ifdef U_SCORE /* most UNIX Fortran compilers add underscore */
     plots_(i1, i2, i3)
#  else
     plots(i1, i2, i3)
#  endif

   int i1, i2, i3;
/*                                                                           */
/* Input:                                                                    */
/*     i1,i2,i3... Dummy parameters - ignored.                               */
/* No output.                                                                */
/*                                                                           */
/* Xlib functions used:                                                      */
/*   XAllocColor, XChangeWindowAttributes, XCreateGC, XCreateSimpleWindow,   */
/*   XMapWindow, XMoveWindow, XNextEvent, XOpenDisplay, XParseColor,         */
/*   XSelectInput, XSetLineAttributes, XSetWMNormalHints, XStoreName         */
/* Xlib C macros used:                                                       */
/*   DefaultColormap, DefaultDepth, DefaultScreen, DefaultScreenOfDisplay,   */
/*   DoesBackingStore                                                        */
/*                                                                           */
/* ------------------------------------------------------------------------  */
/*                                                                           */
   {
   char          *display_name=NULL, cwave[4];
   char          *col_name[]={"black","white","red","green","blue","yellow",
                              "cyan","magenta","indian red","gray63",
                              "magenta3","yellow3","cyan3",
                              "pale violet red","dark cyan","dark magenta"};
   unsigned int  line_width=1;
   int           line_style=LineSolid;
   int           cap_style=CapRound;
   int           join_style=JoinRound;
   int           screen_num, depth, icol, done=0;
   unsigned long valuemask;

   XColor               rgb_val;
   XEvent               event;
   XGCValues            gc_values;
   XSetWindowAttributes win_attr;
   XSizeHints           size_hints;
/*                                                                           */
/* display_name...Specifies the display name, which determines the server    */
/*                to connect to and the communications domain to be used.    */
/* cwave...   String for the number of computed wave.                        */
/* col_name...Specifies the color string (colors are defined in              */
/*            /usr/lib/X11/rgb.txt).                                         */
/* line_width,line_style,cap_style,join_style...Attributes for plotting      */
/*                                              lines.                       */
/* screen_num...Contains screen number.                                      */
/* depth...     Contains the depth (number of planes) of the root window     */
/*              of the specified screen.                                     */
/* icol...      Auxiliary variable for color index.                          */
/* done...      Variable for X event respond.                                */
/* valuemask... Contains mask symbols listed in the structures               */
/*              using bitwise OR (|).                                        */
/* rgb_val...   Specifies desired RGB values (structure).                    */
/* event...     Xevent union.                                                */
/* gc_values... Provides components for the graphics context (structure).    */
/* win_attr...  Contains window attributes (structure).                      */
/* size_hints...Specifies sizes desirable for the window (structure).        */
/*                                                                           */
/* ......................................................................... */
/*                                                                           */
/* Open a display:                                                           */
   if ((display=XOpenDisplay(display_name))==NULL) {
/*   CALCOMPX-01              */
     printf("Error CALCOMPX-01: Cannot connect to X server %s\n",\
             XDisplayName(display_name));
/*   Try to check DISPLAY environment variable or contact your               */
/*   system administrator.                                                   */
     exit(1);
   }
/*                                                                           */
/* Determine the default screen number:                                      */
   screen_num=DefaultScreen(display);
/*                                                                           */
/* Determine default depth of the root window of the specified screen:       */
   depth=DefaultDepth(display, screen_num);
/*                                                                           */
/* Determine default color map:                                              */
   colormap=DefaultColormap(display, screen_num);
/*                                                                           */
/* Set 16 RGB colors:                                                        */
   kolrep=15;
   for (icol=0; icol<16; icol++) {
     XParseColor(display, colormap, col_name[icol], &rgb_val);
     if (!XAllocColor(display, colormap, &rgb_val)) {
/*     CALCOMPX-02            */
       printf("      \
               Error CALCOMPX-02:Can't allocate color= %d\n", icol);
/*     Try to close other graphic application e.g., Netscape,                */
/*     that allocates colors.                                                */
       kolrep=kolrep-1;
     }
     color[icol]=rgb_val.pixel;
   }
   if (kolrep < 15)
     printf("        \
             Color repetition number kolrep= %d\n", kolrep);
/*                                                                           */
/* Create and position a simple window:                                      */
   window=XCreateSimpleWindow(display, RootWindow(display, screen_num),
                        0, 0, WIN_MAX_WIDTH, WIN_MAX_HEIGHT, 0,
                        WhitePixel(display, screen_num),
                        BlackPixel(display, screen_num));
   XMoveWindow(display, window, WIN_MOVE_X, WIN_MOVE_Y);
/*                                                                           */
/* Create default graphics context:                                          */
   valuemask=0;
   gc=XCreateGC(display, window, valuemask, &gc_values);
/*                                                                           */
/* Set line attributes:                                                      */
   XSetLineAttributes(display, gc, line_width, line_style,
                     cap_style, join_style);
/*                                                                           */
/* Set desirable sizes of the window:                                        */
   size_hints.flags= PPosition | PSize | PMinSize |PMaxSize;
   size_hints.min_width =WIN_MIN_WIDTH;
   size_hints.max_width =WIN_MAX_WIDTH;
   size_hints.min_height=WIN_MIN_HEIGHT;
   size_hints.max_height=WIN_MAX_HEIGHT;
   XSetWMNormalHints(display, window, &size_hints);
/*                                                                           */
/* Set window name:                                                          */
   sprintf(cwave,"%d", iwave);
   strcpy (win_name2 , win_name1);
   strncat(win_name2 , cwave, 3);
   XStoreName(display, window, win_name2);
/*                                                                           */
/* Display window:                                                           */
   XMapWindow(display, window);
/*                                                                           */
/* Wait for the Expose event resulting from mapping the window:              */
   XSelectInput(display, window, ExposureMask);
   while (!done) {
     XNextEvent(display, &event);
     switch(event.type) {
/*     Continue when Expose event comes:                                     */
       case Expose:
           done=1;
         break;
       default:
         break;
     }
   }
/*                                                                           */
/* Check and set backing_store:                                              */
   if (DoesBackingStore(DefaultScreenOfDisplay(display)) == Always) {
     valuemask |=CWBackingStore;
     win_attr.backing_store=Always;
     XChangeWindowAttributes(display, window, valuemask, &win_attr);
   }
   else
     printf("        \
             The server does not allow backing store\n");
/*                                                                           */
/* Plotting initialization:                                                  */
   icount=0;
   startx=0.;
   starty=0.;
   oldx  =0.;
   oldy  =0.;
   kolor =0;
   }
/*                                                                           */
/* ========================================================================  */
/*                                                                           */
/* Plot recorded polyline                                                    */
/*                                                                           */
/*                                                        */
/*                                                                           */
#  ifdef U_SCORE /* most UNIX Fortran compilers add underscore */
     plot_(xpage, ypage, ipen)
#  else
     plot(xpage, ypage, ipen)
#  endif

   float *xpage, *ypage;
   int   *ipen;
/*                                                                           */
/* Input:                                                                    */
/*   xpage,ypage... Coordinates of a point, in centimeters from the          */
/*           current reference point (origin), of the position to which      */
/*           the pen is to be moved.                                         */
/*   ipen... A signed integer which controls pen status (up or down)         */
/*           and the origin definition:                                      */
/*           ipen=2... The pen is down during movement, thus drawing a       */
/*             visible line.                                                 */
/*           ipen=3... The pen is up during movement.                        */
/*           ipen=-2 OR -3... A new origin is defined at the terminal        */
/*             position after the movement is completed as if IPEN were      */
/*             positive.                                                     */
/*           ipen=999... Output device is closed.                            */
/* No output.                                                                */
/*                                                                           */
/* Xlib functions used:                                                      */
/*   XDrawLines, XFlush, XLookupString, XNextEvent, XPending, XSelectInput,  */
/*   XStoreName                                                              */
/*                                                                           */
/* ------------------------------------------------------------------------  */
/*                                                                           */
   {
   char           buffer[1], win_name3[42];
   int            buf_size=1, done=0, ipenc, nchar;
   float          xpagec, ypagec;

   KeySym         keysym;
   XComposeStatus compose;
   XEvent         event;
/*                                                                           */
/* buffer...   String that contains key event.                               */
/* win_name3...String for window name.                                       */
/* buf_size... Length of the buffer.                                         */
/* done...     Variable for X event respond.                                 */
/* nchar...    Contains length of string in buffer.                          */
/* xpagec,ypagec,ipenc...C language equivalents to Fortran XPAGE,YPAGE,IPEN. */
/* keysym...   Contains ASCII string computed from key event.                */
/* compose...  Contains compose key state information.                       */
/* event...    Xevent union.                                                 */
/*                                                                           */
/* ......................................................................... */
/*                                                                           */
/* Normalize coordinates to window size:                                     */
   xpagec=WIN_MAX_WIDTH*(*xpage-XMIN)/(XMAX-XMIN);
   ypagec=WIN_MAX_HEIGHT-(*ypage-YMIN)*WIN_MAX_HEIGHT/(YMAX-YMIN);
   ipenc=*ipen;
/*                                                                           */
/* Recording or plotting the polyline:                                       */
   if (abs(ipenc) == 2) {
     if (icount == 0) {
       icount=1;
       ln_points[0].x=startx+oldx;
       ln_points[0].y=starty+oldy;
     }
     if (icount < mcount)
       if (xpagec != oldx || ypagec != oldy) {
         icount=icount+1;
         ln_points[icount-1].x=startx+xpagec;
         ln_points[icount-1].y=starty+ypagec;
       }
     else {
       XDrawLines (display, window, gc, ln_points, icount, CoordModeOrigin);
       icount=1;
       ln_points[0].x=startx+oldx;
       ln_points[0].y=starty+oldy;
       if (xpagec != oldx || ypagec != oldy) {
         icount=icount+1;
         ln_points[icount-1].x=startx+xpagec;
         ln_points[icount-1].y=starty+ypagec;
       }
     }
   }
   if (ipenc != 2) {
     if (icount > 0) {
       if (icount == 1) {
         icount=2;
         ln_points[1].x=ln_points[0].x;
         ln_points[1].y=ln_points[0].y;
       }
       XDrawLines (display, window, gc, ln_points, icount, CoordModeOrigin);
       icount=0;
     }
   }
/*                                                                           */
/* Moving the origin:                                                        */
   if (ipenc >= 0) {
     oldx=xpagec;
     oldy=ypagec;
   }
   else {
     startx=startx+xpagec;
     starty=starty+ypagec;
     oldx=0.;
     oldy=0.;
   }
/*                                                                           */
/* Flush the request buffer:                                                 */
   XPending(display);
/*                                                                           */
/* Closing Xlib interface:                                                   */
   if (ipenc >= 999) {
/*   Change a name of the window:                                            */
     strcpy(win_name3, win_name2);
     strcat(win_name3, " - press ENTER to continue");
     XStoreName(display, window, win_name3);
/*   Read and respond to Xlib events:                                        */
     XSelectInput(display, window, KeyPressMask);
     while (!done) {
       XNextEvent(display, &event);
       switch(event.type) {
/*       Continue when Return or Enter key is pressed:                       */
         case KeyPress:
           nchar=XLookupString(&event.xkey, buffer, buf_size, &keysym,
                               &compose);
           if((keysym==XK_Return) || (keysym==XK_KP_Enter))
             done=1;
           break;
         default:
           break;
       }
     }
     iwave=iwave+1;
/*                                                                           */
/*   Change a name of the window:                                            */
     XStoreName(display, window, win_name2);
/*                                                                           */
/*   Send all queued requests to the server:                                 */
     XFlush(display);
     }
   }
/*                                                                           */
/* ========================================================================  */
/*                                                                           */
/* Plot recorded polyline or change the color                                */
/*                                                                           */
/*                                                      */
/*                                                                           */
#  ifdef U_SCORE /* most UNIX Fortran compilers add underscore */
     newpen_(inp)
#  else
     newpen(inp)
#  endif

   int *inp;
/*                                                                           */
/* Input:                                                                    */
/*   inp...  Number of the pen or color index to be selected.                */
/* No output.                                                                */
/*                                                                           */
/* Xlib functions used:                                                      */
/*   XDrawLines, XSetForeground                                              */
/*                                                                           */
/* ------------------------------------------------------------------------  */
/*                                                                           */
   {
   unsigned int iaux;
   int          inpc;
/*                                                                           */
/* iaux...Auxiliary variable.                                                */
/* inpc...C language equivalent to Fortran INP.                              */
/* ......................................................................... */
/*                                                                           */
   inpc=*inp;
   if (inpc != kolor) {
/*                                                                           */
/*   Plotting the recorded polyline:                                         */
     if (icount > 0) {
       if (icount == 1) {
         icount=2;
         ln_points[1].x=ln_points[0].x;
         ln_points[1].y=ln_points[0].y;
       }
       XDrawLines (display, window, gc, ln_points, icount, CoordModeOrigin);
       icount=0;
     }
   }
/*                                                                           */
/* Changing the color indices:                                               */
/* (for kolrep > 1 , colors 2 to kolrep are periodically repeated)           */
   if (kolrep > 1)
     iaux=((inpc-2) % (kolrep-1))+2;
   else
     iaux=inpc;
   XSetForeground(display, gc, color[iaux]);
   kolor=inpc;
   }
/* ========================================================================  */
/*                                                                     
*/