/*
*/ /* 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; } /* ======================================================================== */ /*