xgraph.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:32k
- /* $Header: /usr/src/mash/repository/vint/xgraph/xgraph.c,v 1.3 1999/12/19 00:52:07 heideman Exp $ */
- /*
- * xgraph - A Simple Plotter for X
- *
- * David Harrison
- * University of California, Berkeley
- * 1986, 1987, 1988, 1989
- *
- * Please see copyright.h concerning the formal reproduction rights
- * of this software.
- *
- * $Log: xgraph.c,v $
- * Revision 1.3 1999/12/19 00:52:07 heideman
- * warning suppresion, slightly different flot ahndling
- *
- * Revision 1.2 1999/12/03 23:17:46 heideman
- * apply xgraph_no_animation.patch
- *
- * Revision 1.1.1.1 1999/12/03 23:15:52 heideman
- * xgraph-12.0
- *
- */
- #ifndef lint
- static char rcsid[] = "$Id: xgraph.c,v 1.3 1999/12/19 00:52:07 heideman Exp $";
- #endif
- #include "copyright.h"
- #include <stdio.h>
- #include <math.h>
- #include <pwd.h>
- #include <ctype.h>
- #include "xgraph.h"
- #include "xtb.h"
- #include "hard_devices.h"
- #include "params.h"
- extern void init_X();
- extern void do_error();
- #ifdef DO_DER
- extern void Bounds();
- #endif /* DO_DER */
- static char *tildeExpand();
- static void ReverseIt();
- static void Traverse();
- static int XErrHandler();
- NewDataSet PlotData[MAXSETS],
- DataD1[MAXSETS],
- DataD2[MAXSETS];
- XSegment *Xsegs[2]; /* Point space for X */
- /* Basic transformation stuff */
- double llx,
- lly,
- urx,
- ury; /* Bounding box of all data */
- static XContext win_context = (XContext) 0;
- /* Other globally set defaults */
- Display *disp; /* Open display */
- Visual *vis; /* Standard visual */
- Colormap cmap; /* Standard colormap */
- int screen; /* Screen number */
- int depth; /* Depth of screen */
- int numFiles = 0; /* Number of input files */
- char *inFileNames[MAXSETS]; /* File names */
- /* Total number of active windows */
- int Num_Windows = 0;
- char *Prog_Name;
- char *disp_name;
- main(argc, argv)
- int argc;
- char *argv[];
- /*
- * This sets up the hard-wired defaults and reads the X defaults.
- * The command line format is: xgraph [host:display].
- */
- {
- Window primary,
- NewWindow();
- XEvent theEvent;
- LocalWin *win_info;
- Cursor zoomCursor;
- FILE *strm;
- XColor fg_color,
- bg_color;
- char keys[MAXKEYS];
- int nbytes,
- idx,
- maxitems = 0,
- flags;
- int errs = 0;
- /* Open up new display */
- Prog_Name = argv[0];
- disp_name = "";
- /* Parse the argument list looking for input files */
- flags = ParseArgs(argc, argv, 0);
- if (flags == D_XWINDOWS) {
- disp = XOpenDisplay(disp_name);
- if (!disp) {
- (void) fprintf(stderr,
- "%s: cannot open display `%s'n",
- argv[0], disp_name);
- exit(1);
- }
- XSetErrorHandler(XErrHandler);
- }
- /* Set up hard-wired defaults and allocate spaces */
- InitSets(flags);
- /* Read X defaults and override hard-coded defaults */
- if (PM_INT("Output Device") == D_XWINDOWS)
- ReadDefaults();
- /* Read the data into the data sets */
- llx = lly = MAXFLOAT;
- urx = ury = -MAXFLOAT;
- for (idx = 0; idx < numFiles; idx++) {
- strm = fopen(inFileNames[idx], "r");
- if (!strm) {
- (void) fprintf(stderr, "Warning: cannot open file `%s'n",
- inFileNames[idx]);
- }
- else {
- if ((maxitems = ReadData(strm, inFileNames[idx])) < 0) {
- errs++;
- }
- (void) fclose(strm);
- }
- }
- if (!numFiles) {
- if ((maxitems = ReadData(stdin, (char *) 0)) < 0) {
- errs++;
- }
- }
- if (errs) {
- (void) fprintf(stderr, "Problems found with input data.n");
- exit(1);
- }
- /* Parse the argument list to set options */
- (void) ParseArgs(argc, argv, 1);
- if (PM_BOOL("Animate")) param_set("TitleText",STR,"Animated X Graph");
- if (maxitems == 0) {
- (void) fprintf(stderr, "Nothing to plot.n");
- exit(1);
- }
- Xsegs[0] = (XSegment *) Malloc((unsigned) (maxitems * sizeof(XSegment)));
- Xsegs[1] = (XSegment *) Malloc((unsigned) (maxitems * sizeof(XSegment)));
- /* Reverse Video Hack */
- if (PM_BOOL("ReverseVideo"))
- ReverseIt();
- hard_init();
- if (PM_BOOL("Debug")) {
- if (PM_INT("Output Device") == D_XWINDOWS)
- (void) XSynchronize(disp, 1);
- param_dump();
- }
- /* Logarithmic and bounding box computation */
- flags = 0;
- if (PM_BOOL("LogX"))
- flags |= LOG_X;
- if (PM_BOOL("LogY"))
- flags |= LOG_Y;
- if (PM_BOOL("StackGraph"))
- flags |= STK;
- if (PM_BOOL("FitX"))
- flags |= FITX;
- if (PM_BOOL("FitY"))
- flags |= FITY;
- Traverse(flags);
- /* Nasty hack here for bar graphs */
- if (PM_BOOL("BarGraph")) {
- double base;
- llx -= PM_DBL("BarWidth");
- urx += PM_DBL("BarWidth");
- base = PM_DBL("BarBase");
- if (base < lly)
- lly = base;
- if (base > ury)
- ury = base;
- }
- /* Create initial window */
- if (PM_INT("Output Device") == D_XWINDOWS) {
- double asp;
- asp = 1.0;
- xtb_init(disp, screen, PM_PIXEL("Foreground"), PM_PIXEL("Background"),
- PM_FONT("LabelFont"));
-
- primary = NewWindow(Prog_Name,
- PM_DBL("XLowLimit"), PM_DBL("YLowLimit"),
- PM_DBL("XHighLimit"), PM_DBL("YHighLimit"),
- asp,0);
- if (!primary) {
- (void) fprintf(stderr, "Main window would not openn");
- exit(1);
- }
- zoomCursor = XCreateFontCursor(disp, XC_sizing);
- fg_color = PM_COLOR("Foreground");
- bg_color = PM_COLOR("Background");
- XRecolorCursor(disp, zoomCursor, &fg_color, &bg_color);
- Num_Windows = 1;
- while (Num_Windows > 0) {
- XNextEvent(disp, &theEvent);
- if (xtb_dispatch(&theEvent) != XTB_NOTDEF)
- continue;
- if (XFindContext(theEvent.xany.display,
- theEvent.xany.window,
- win_context, (caddr_t *) & win_info)) {
- /* Nothing found */
- continue;
- }
- switch (theEvent.type) {
- case Expose:
- if (theEvent.xexpose.count <= 0) {
- XWindowAttributes win_attr;
- XGetWindowAttributes(disp, theEvent.xany.window, &win_attr);
- win_info->dev_info.area_w = win_attr.width;
- win_info->dev_info.area_h = win_attr.height;
- init_X(win_info->dev_info.user_state);
- EraseData(win_info);
- DrawWindow(win_info);
- }
- break;
- case KeyPress:
- nbytes = XLookupString(&theEvent.xkey, keys, MAXKEYS,
- (KeySym *) 0, (XComposeStatus *) 0);
- for (idx = 0; idx < nbytes; idx++) {
- if (keys[idx] == CONTROL_D) {
- /* Delete this window */
- DelWindow(theEvent.xkey.window, win_info);
- }
- else if (keys[idx] == CONTROL_C) {
- /* Exit program */
- Num_Windows = 0;
- }
- else if (keys[idx] == 'h') {
- PrintWindow(theEvent.xany.window, win_info);
- }
- }
- break;
- case ButtonPress:
- /* Handle creating a new window */
- Num_Windows += HandleZoom(Prog_Name,
- &theEvent.xbutton,
- win_info, zoomCursor);
- break;
- default:
- (void) fprintf(stderr, "Unknown event type: %xn",
- theEvent.type);
- break;
- }
- }
- }
- else {
- int Device = PM_INT("Output Device");
- int dflag = strcmp(PM_STR("Disposition"), "To Device") == 0;
- primary = NewWindow(Prog_Name,
- PM_DBL("XLowLimit"), PM_DBL("YLowLimit"),
- PM_DBL("XHighLimit"), PM_DBL("YHighLimit"),
- 1.0,0);
- do_hardcopy(Prog_Name, primary,
- hard_devices[Device].dev_init,
- dflag ? hard_devices[Device].dev_spec : 0,
- PM_STR("FileOrDev"), (double) 19,
- hard_devices[Device].dev_title_font,
- hard_devices[Device].dev_title_size,
- hard_devices[Device].dev_axis_font,
- hard_devices[Device].dev_axis_size,
- PM_BOOL("Document") * D_DOCU);
- }
- return 0;
- }
- #define BLACK_THRES 30000
- static void
- ReversePix(param_name)
- char *param_name; /* Name of color parameter */
- /*
- * Looks up `param_name' in the parameters database. If found, the
- * color is examined and judged to be either black or white based
- * upon its red, green, and blue intensities. The sense of the
- * color is then reversed and reset to its opposite.
- */
- {
- params val;
- if (param_get(param_name, &val)) {
- if ((val.pixv.value.red < BLACK_THRES) &&
- (val.pixv.value.green < BLACK_THRES) &&
- (val.pixv.value.blue < BLACK_THRES)) {
- /* Color is black */
- param_reset(param_name, "white");
- }
- else {
- /* Color is white */
- param_reset(param_name, "black");
- }
- }
- else {
- (void) fprintf(stderr, "Cannot reverse color `%s'n", param_name);
- }
- }
- static void
- ReverseIt()
- /*
- * This routine attempts to implement reverse video. It steps through
- * all of the important colors in the parameters database and makes
- * black white (and vice versa).
- */
- {
- int i;
- char buf[1024];
- for (i = 0; i < MAXATTR; i++) {
- (void) sprintf(buf, "%d.Color", i);
- ReversePix(buf);
- }
- ReversePix("Foreground");
- ReversePix("Border");
- ReversePix("ZeroColor");
- ReversePix("Background");
- }
- static void
- Traverse(flags)
- int flags; /* Options */
- /*
- * Traverses through all of the data applying certain options to the
- * data and computing the overall bounding box. The flags are:
- * LOG_X Take the log of the X axis
- * LOG_Y Take the log of the Y axis
- * STK Stack coordinates.
- * FITX Fit x-coordinates from zero to one
- * FITY Fit y-coordinates from zero to one
- */
- {
- int i,
- j;
- PointList *spot;
- PointList *pspot;
- static char *paramstr[] =
- {
- "Cannot plot negative %s valuesn",
- "when the logarithmic option is selected.n",
- "Number of points in %d and %d don't match for stacking.n",
- "Point %d in %d and %d doesn't match for stacking.n",
- "Set %d has 0 %s.n"
- };
- if (flags & (FITX|FITY))
- for (i = 0; i < MAXSETS; i++)
- for (spot = PlotData[i].list; spot; spot = spot->next) {
- float minx, maxx, miny, maxy;
- minx = maxx = spot->xvec[0];
- maxy = miny = spot->yvec[0];
- for (j = 1; j < spot->numPoints; j++) {
- minx = MIN(minx, spot->xvec[j]);
- miny = MIN(miny, spot->yvec[j]);
- maxx = MAX(maxx, spot->xvec[j]);
- maxy = MAX(maxy, spot->yvec[j]);
- }
- maxx = maxx - minx;
- maxy = maxy - miny;
- if (maxx == 0.0) {
- (void) fprintf(stderr, paramstr[3], i, "width");
- maxx = 1.0;
- }
- if (maxy == 0.0) {
- (void) fprintf(stderr, paramstr[3], i, "height");
- maxy = 1.0;
- }
- switch (flags & (FITX|FITY)) {
- case FITX:
- for (j = 0; j < spot->numPoints; j++)
- spot->xvec[j] = (-minx + spot->xvec[j]) / maxx;
- break;
- case FITY:
- for (j = 0; j < spot->numPoints; j++)
- spot->yvec[j] = (-miny + spot->yvec[j]) / maxy;
- break;
- case FITX|FITY:
- for (j = 0; j < spot->numPoints; j++) {
- spot->xvec[j] = (-minx + spot->xvec[j]) / maxx;
- spot->yvec[j] = (-miny + spot->yvec[j]) / maxy;
- }
- break;
- default:
- abort();
- }
- }
- if (flags & STK)
- for (i = 1; i < MAXSETS; i++) {
- for (spot = PlotData[i].list, pspot = PlotData[i - 1].list;
- spot && pspot; spot = spot->next, pspot = pspot->next) {
- if (spot->numPoints != pspot->numPoints) {
- (void) fprintf(stderr, paramstr[2], i - 1, i);
- exit(1);
- }
- for (j = 0; j < spot->numPoints; j++) {
- if (spot->xvec[j] != pspot->xvec[j]) {
- (void) fprintf(stderr, paramstr[3], j, i - 1, i);
- exit(1);
- }
- spot->yvec[j] += pspot->yvec[j];
- }
- }
- }
- for (i = 0; i < MAXSETS; i++) {
- for (spot = PlotData[i].list; spot; spot = spot->next) {
- for (j = 0; j < spot->numPoints; j++) {
- if (flags & LOG_Y) {
- if (spot->yvec[j] > 0.0) {
- spot->yvec[j] = log10(spot->yvec[j]);
- }
- else if (spot->yvec[j] == 0)
- spot->yvec[j] = 0.0;
- else {
- (void) fprintf(stderr, paramstr[0], "Y");
- (void) fprintf(stderr, paramstr[1]);
- exit(1);
- }
- }
- if (flags & LOG_X) {
- if (spot->xvec[j] > 0.0) {
- spot->xvec[j] = log10(spot->xvec[j]);
- }
- else if (spot->xvec[j] == 0)
- spot->xvec[j] = 0.0;
- else {
- (void) fprintf(stderr, paramstr[0], "X");
- (void) fprintf(stderr, paramstr[1]);
- exit(1);
- }
- }
- /* Update global bounding box */
- if (spot->xvec[j] < llx)
- llx = spot->xvec[j];
- if (spot->xvec[j] > urx)
- urx = spot->xvec[j];
- if (spot->yvec[j] < lly)
- lly = spot->yvec[j];
- if (spot->yvec[j] > ury)
- ury = spot->yvec[j];
- }
- }
- }
- }
- /*
- * Button handling functions
- */
- /*ARGSUSED*/
- xtb_hret
- del_func(win, bval, info)
- Window win; /* Button window */
- int bval; /* Button value */
- char *info; /* User information */
- /*
- * This routine is called when the `Close' button is pressed in
- * an xgraph window. It causes the window to go away.
- */
- {
- Window the_win = (Window) info;
- LocalWin *win_info;
- xtb_bt_set(win, 1, (char *) 0, 0);
- if (!XFindContext(disp, the_win, win_context, (caddr_t *) & win_info)) {
- if (win_info->flags & HARDCOPY_IN_PROGRESS) {
- do_error("Can't close window whilenhardcopy dialog is posted.n");
- xtb_bt_set(win, 0, (char *) 0, 0);
- }
- else {
- DelWindow(the_win, win_info);
- }
- }
- return XTB_HANDLED;
- }
- /*ARGSUSED*/
- xtb_hret
- hcpy_func(win, bval, info)
- Window win; /* Button Window */
- int bval; /* Button value */
- char *info; /* User Information */
- /*
- * This routine is called when the hardcopy button is pressed
- * in an xgraph window. It causes the output dialog to be
- * posted.
- */
- {
- Window the_win = (Window) info;
- LocalWin *win_info;
- xtb_bt_set(win, 1, (char *) 0, 0);
- if (!XFindContext(disp, the_win, win_context, (caddr_t *) & win_info)) {
- win_info->flags |= HARDCOPY_IN_PROGRESS;
- PrintWindow(the_win, win_info);
- win_info->flags &= (~HARDCOPY_IN_PROGRESS);
- }
- xtb_bt_set(win, 0, (char *) 0, 0);
- return XTB_HANDLED;
- }
- static
- /*ARGSUSED*/
- xtb_hret
- abt_func(win, bval, info)
- Window win; /* Button window */
- int bval; /* Button value */
- char *info; /* User information */
- {
- static char *msg_fmt =
- "Version %sn
- XGraph + Animation and Derivativesn
- Modification of code by David Harrisonn
- University of California, Berkeleyn
- (davidh@ic.Berkeley.EDU or n
- ...!ucbvax!ucbic!davidh)n
- Animation, differentiation, and a few othern
- new features added by Paul Walker,n
- National Center for Supercomputer Applicationsn
- and Univ. Illinois at U-C Dept of Physics.n
- Send comments or suggestions ton
- pwalker@ncsa.uiuc.edun";
- static int active = 0;
- char msg_buf[1024];
- if (!active) {
- active = 1;
- xtb_bt_set(win, 1, (char *) 0, 0);
- (void) sprintf(msg_buf, msg_fmt, VERSION_STRING);
- msg_box("XGraph", msg_buf);
- xtb_bt_set(win, 0, (char *) 0, 0);
- active = 0;
- }
- return XTB_HANDLED;
- }
- #ifdef DO_DER
- static
- /*ARGSUSED PW*/
- xtb_hret
- rew_func(win, bval, info)
- Window win; /* Button window */
- int bval; /* Button value */
- char *info; /* User information */
- {
- /* This routine added, Paul Walker, to rewind the animation and start
- it over. The only even moderatly tricky part is erasing the last
- item, which still lives, and redrawing the axis. I do it by just
- copying the "Expose" information from the main routine. */
- Window the_win = (Window) info;
- LocalWin *win_info;
- /* Set animation to True */
- param_set("Animate",BOOL,"on");
- if (!XFindContext(disp, the_win, win_context, (caddr_t *) & win_info)) {
- XWindowAttributes win_attr;
- XGetWindowAttributes(disp, the_win, &win_attr);
- win_info->dev_info.area_w = win_attr.width;
- win_info->dev_info.area_h = win_attr.height;
- init_X(win_info->dev_info.user_state);
- EraseData (win_info);
- DrawWindow(win_info);
- }
- return XTB_HANDLED;
- }
- static
- /*ARGSUSED PW*/
- xtb_hret
- der_func(win, bval, info)
- Window win; /* Button window */
- int bval; /* Button value */
- char *info; /* User information */
- {
- /* This routine added, Paul Walker, to rewind the animation and start
- it over. The only even moderatly tricky part is erasing the last
- item, which still lives, and redrawing the axis. I do it by just
- copying the "Expose" information from the main routine. */
- Window the_win = (Window) info;
- Window new_win;
- LocalWin *win_info;
- double loX,loY,hiX,hiY,asp;
- static char *msg_fmt =
- "Version %sn
- Currently unable to displayn
- or calculate derivativesn
- higher than 2nd ordern";
- static int active = 0;
- char msg_buf[1024];
- XFindContext(disp, the_win, win_context, (caddr_t *) & win_info);
- if (win_info->DOrder == 2) {
- if (!active) {
- active = 1;
- xtb_bt_set(win, 1, (char *) 0, 0);
- (void) sprintf(msg_buf, msg_fmt, VERSION_STRING);
- msg_box("XGraph", msg_buf);
- xtb_bt_set(win, 0, (char *) 0, 0);
- active = 0;
- }
- return XTB_HANDLED;
- }
- Num_Windows += 1;
- asp = 1.0;
- Bounds(&loX,&loY,&hiX,&hiY,win_info->DOrder+1);
- new_win = NewWindow("Derivatives", loX, loY, hiX, hiY, asp,
- win_info->DOrder+1);
- if (!XFindContext(disp, new_win, win_context, (caddr_t *) & win_info)) {
- XWindowAttributes win_attr;
- XGetWindowAttributes(disp, new_win, &win_attr);
- win_info->dev_info.area_w = win_attr.width;
- win_info->dev_info.area_h = win_attr.height;
- init_X(win_info->dev_info.user_state);
- EraseData (win_info);
- DrawWindow(win_info);
- }
- return XTB_HANDLED;
- }
- static
- /*ARGSUSED PW*/
- xtb_hret
- rpl_func(win, bval, info)
- Window win; /* Button window */
- int bval; /* Button value */
- char *info; /* User information */
- {
- /* Puts us back into static mode ... */
- Window the_win = (Window) info;
- LocalWin *win_info;
- /* Set animation to True */
- param_set("Animate",BOOL,"off");
- if (!XFindContext(disp, the_win, win_context, (caddr_t *) & win_info)) {
- XWindowAttributes win_attr;
- XGetWindowAttributes(disp, the_win, &win_attr);
- win_info->dev_info.area_w = win_attr.width;
- win_info->dev_info.area_h = win_attr.height;
- init_X(win_info->dev_info.user_state);
- EraseData (win_info);
- DrawWindow(win_info);
- }
- return XTB_HANDLED;
- }
- /* End change PW */
- #endif /* DO_DER */
- #define NORMSIZE 600
- #define MINDIM 100
- Window
- NewWindow(progname, lowX, lowY, upX, upY, asp, DO)
- char *progname; /* Name of program */
- double lowX,
- lowY; /* Lower left corner */
- double upX,
- upY; /* Upper right corner */
- double asp; /* Aspect ratio */
- int DO; /* Derivative Order. */
- /*
- * Creates and maps a new window. This includes allocating its
- * local structure and associating it with the XId for the window.
- * The aspect ratio is specified as the ratio of width over height.
- */
- {
- Window new_window;
- LocalWin *new_info;
- static Cursor theCursor = (Cursor) 0;
- XSizeHints sizehints;
- XSetWindowAttributes wattr;
- XWMHints wmhints;
- XColor fg_color,
- bg_color;
- int geo_mask;
- int width,
- height;
- unsigned long wamask;
- char defSpec[120];
- double pad;
- new_info = (LocalWin *) Malloc(sizeof(LocalWin));
- new_info->DOrder = DO;
- if (upX > lowX) {
- new_info->loX = lowX;
- new_info->hiX = upX;
- }
- else {
- new_info->loX = llx;
- new_info->hiX = urx;
- }
- if (upY > lowY) {
- new_info->loY = lowY;
- new_info->hiY = upY;
- }
- else {
- new_info->loY = lly;
- new_info->hiY = ury;
- }
- /* Increase the padding for aesthetics */
- if (new_info->hiX - new_info->loX == 0.0) {
- pad = MAX(0.5, fabs(new_info->hiX / 2.0));
- new_info->hiX += pad;
- new_info->loX -= pad;
- }
- if (new_info->hiY - new_info->loY == 0) {
- pad = MAX(0.5, fabs(ury / 2.0));
- new_info->hiY += pad;
- new_info->loY -= pad;
- }
- /* Add 10% padding to bounding box (div by 20 yeilds 5%) */
- pad = (new_info->hiX - new_info->loX) / 20.0;
- new_info->loX -= pad;
- new_info->hiX += pad;
- pad = (new_info->hiY - new_info->loY) / 20.0;
- new_info->loY -= pad;
- new_info->hiY += pad;
- /* Aspect ratio computation */
- if (asp < 1.0) {
- height = NORMSIZE;
- width = ((int) (((double) NORMSIZE) * asp));
- }
- else {
- width = NORMSIZE;
- height = ((int) (((double) NORMSIZE) / asp));
- }
- height = MAX(MINDIM, height);
- width = MAX(MINDIM, width);
- if (PM_INT("Output Device") == D_XWINDOWS) {
- (void) sprintf(defSpec, "%dx%d+100+100", width, height);
- wamask = CWBackPixel | CWBorderPixel | CWColormap;
- wattr.background_pixel = PM_PIXEL("Background");
- wattr.border_pixel = PM_PIXEL("Border");
- wattr.colormap = cmap;
- sizehints.flags = PPosition | PSize;
- sizehints.x = sizehints.y = 100;
- sizehints.width = width;
- sizehints.height = height;
- geo_mask = XParseGeometry(PM_STR("Geometry"),
- &sizehints.x, &sizehints.y,
- (unsigned int *) &sizehints.width,
- (unsigned int *) &sizehints.height);
- if (geo_mask & (XValue|YValue))
- sizehints.flags = (sizehints.flags & ~PPosition) | USPosition;
- if (geo_mask & (WidthValue | HeightValue))
- sizehints.flags = (sizehints.flags & ~PSize) | USSize;
- new_window = XCreateWindow(disp, RootWindow(disp, screen),
- sizehints.x, sizehints.y,
- (unsigned int) sizehints.width,
- (unsigned int) sizehints.height,
- (unsigned int) PM_INT("BorderSize"),
- depth, InputOutput, vis,
- wamask, &wattr);
- if (new_window) {
- xtb_frame cl_frame,
- hd_frame,
- ab_frame,
- rw_frame,
- rp_frame,
- dx_frame;
- XStoreName(disp, new_window, progname);
- XSetIconName(disp, new_window, progname);
- wmhints.flags = InputHint | StateHint;
- wmhints.input = True;
- wmhints.initial_state = NormalState;
- XSetWMHints(disp, new_window, &wmhints);
- XSetWMNormalHints(disp, new_window, &sizehints);
- /* Set device info */
- set_X(new_window, &(new_info->dev_info));
- if (!PM_BOOL("NoButton")) {
- /* Make buttons */
- xtb_bt_new(new_window, "Close", del_func,
- (xtb_data) new_window, &cl_frame);
- new_info->close = cl_frame.win;
- XMoveWindow(disp, new_info->close, (int) BTNPAD, (int) BTNPAD);
- xtb_bt_new(new_window, "Hdcpy", hcpy_func,
- (xtb_data) new_window, &hd_frame);
- new_info->hardcopy = hd_frame.win;
- XMoveWindow(disp, new_info->hardcopy,
- (int) (BTNPAD + cl_frame.width + BTNINTER),
- BTNPAD);
- xtb_bt_new(new_window, "About", abt_func,
- (xtb_data) new_window, &ab_frame);
- new_info->about = ab_frame.win;
- XMoveWindow(disp, new_info->about,
- (int) (BTNPAD + cl_frame.width + BTNINTER +
- hd_frame.width + BTNINTER), BTNPAD);
- #ifdef DO_DER
- /* These buttons added PW */
- xtb_bt_new(new_window, "Anim", rew_func,
- (xtb_data) new_window, &rw_frame);
- new_info->rewind = rw_frame.win;
- XMoveWindow(disp, new_info->rewind,
- (int) (BTNPAD + cl_frame.width + BTNINTER +
- hd_frame.width + BTNINTER +
- ab_frame.width + BTNINTER), BTNPAD);
- xtb_bt_new(new_window, "Replot", rpl_func,
- (xtb_data) new_window, &rp_frame);
- new_info->replot = rp_frame.win;
- XMoveWindow(disp, new_info->replot,
- (int) (BTNPAD + cl_frame.width + BTNINTER +
- hd_frame.width + BTNINTER +
- ab_frame.width + BTNINTER +
- rw_frame.width + BTNINTER), BTNPAD);
- xtb_bt_new(new_window, "Deriv", der_func,
- (xtb_data) new_window, &dx_frame);
- new_info->deriv = dx_frame.win;
- XMoveWindow(disp, new_info->deriv,
- (int) (BTNPAD + cl_frame.width + BTNINTER +
- hd_frame.width + BTNINTER +
- ab_frame.width + BTNINTER +
- rw_frame.width + BTNINTER +
- rp_frame.width + BTNINTER), BTNPAD);
- #endif /* DO_DER */
- new_info->flags = 0;
- }
- XSelectInput(disp, new_window,
- ExposureMask | KeyPressMask | ButtonPressMask);
- if (!theCursor) {
- theCursor = XCreateFontCursor(disp, XC_top_left_arrow);
- fg_color = PM_COLOR("Foreground");
- bg_color = PM_COLOR("Background");
- XRecolorCursor(disp, theCursor, &fg_color, &bg_color);
- }
- XDefineCursor(disp, new_window, theCursor);
- if (!win_context) {
- win_context = XUniqueContext();
- }
- XSaveContext(disp, new_window, win_context, (caddr_t) new_info);
- XMapWindow(disp, new_window);
- return new_window;
- }
- else {
- return (Window) 0;
- }
- }
- else {
- new_info->dev_info.area_h = 1.0;
- new_info->dev_info.area_w = 1.0;
- return ((Window) new_info);
- }
- }
- DelWindow(win, win_info)
- Window win; /* Window */
- LocalWin *win_info; /* Local Info */
- /*
- * This routine actually deletes the specified window and
- * decrements the window count.
- */
- {
- xtb_data info;
- XDeleteContext(disp, win, win_context);
- xtb_bt_del(win_info->close, &info);
- xtb_bt_del(win_info->hardcopy, &info);
- xtb_bt_del(win_info->about, &info);
- Free((char *) win_info);
- XDestroyWindow(disp, win);
- Num_Windows -= 1;
- }
- PrintWindow(win, win_info)
- Window win; /* Window */
- LocalWin *win_info; /* Local Info */
- /*
- * This routine posts a dialog asking about the hardcopy
- * options desired. If the user hits `OK', the hard
- * copy is performed.
- */
- {
- ho_dialog(win, Prog_Name, (char *) win_info);
- }
- static XRectangle boxEcho;
- static GC echoGC = (GC) 0;
- #define DRAWBOX
- if (startX < curX) {
- boxEcho.x = startX;
- boxEcho.width = curX - startX;
- } else {
- boxEcho.x = curX;
- boxEcho.width = startX - curX;
- }
- if (startY < curY) {
- boxEcho.y = startY;
- boxEcho.height = curY - startY;
- } else {
- boxEcho.y = curY;
- boxEcho.height = startY - curY;
- }
- XDrawRectangles(disp, win, echoGC, &boxEcho, 1);
- #define TRANX(xval)
- (((double) ((xval) - wi->XOrgX)) * wi->XUnitsPerPixel + wi->UsrOrgX)
- #define TRANY(yval)
- (wi->UsrOppY - (((double) ((yval) - wi->XOrgY)) * wi->YUnitsPerPixel))
- int
- HandleZoom(progname, evt, wi, cur)
- char *progname;
- XButtonPressedEvent *evt;
- LocalWin *wi;
- Cursor cur;
- {
- Window win,
- new_win;
- Window root_rtn,
- child_rtn;
- XEvent theEvent;
- int startX,
- startY,
- curX,
- curY,
- newX,
- newY,
- stopFlag,
- numwin = 0;
- int root_x,
- root_y;
- unsigned int mask_rtn;
- double loX,
- loY,
- hiX,
- hiY,
- asp;
- win = evt->window;
- if (XGrabPointer(disp, win, True,
- (unsigned int) (ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | PointerMotionHintMask),
- GrabModeAsync, GrabModeAsync,
- win, cur, CurrentTime) != GrabSuccess) {
- XBell(disp, 0);
- return 0;
- }
- if (echoGC == (GC) 0) {
- unsigned long gcmask;
- XGCValues gcvals;
- gcmask = GCForeground | GCFunction;
- gcvals.foreground = PM_PIXEL("ZeroColor") ^ PM_PIXEL("Background");
- gcvals.function = GXxor;
- echoGC = XCreateGC(disp, win, gcmask, &gcvals);
- }
- startX = evt->x;
- startY = evt->y;
- XQueryPointer(disp, win, &root_rtn, &child_rtn, &root_x, &root_y,
- &curX, &curY, &mask_rtn);
- /* Draw first box */
- DRAWBOX;
- stopFlag = 0;
- while (!stopFlag) {
- XNextEvent(disp, &theEvent);
- switch (theEvent.xany.type) {
- case MotionNotify:
- XQueryPointer(disp, win, &root_rtn, &child_rtn, &root_x, &root_y,
- &newX, &newY, &mask_rtn);
- /* Undraw the old one */
- DRAWBOX;
- /* Draw the new one */
- curX = newX;
- curY = newY;
- DRAWBOX;
- break;
- case ButtonRelease:
- DRAWBOX;
- XUngrabPointer(disp, CurrentTime);
- stopFlag = 1;
- if ((startX - curX != 0) && (startY - curY != 0)) {
- /* Figure out relative bounding box */
- loX = TRANX(startX);
- loY = TRANY(startY);
- hiX = TRANX(curX);
- hiY = TRANY(curY);
- if (loX > hiX) {
- double temp;
- temp = hiX;
- hiX = loX;
- loX = temp;
- }
- if (loY > hiY) {
- double temp;
- temp = hiY;
- hiY = loY;
- loY = temp;
- }
- /* physical aspect ratio */
- asp = ((double) ABS(startX - curX)) /
- ((double) ABS(startY - curY));
- new_win = NewWindow(progname, loX, loY, hiX, hiY, asp,
- wi->DOrder);
- if (new_win) {
- numwin = 1;
- }
- else {
- numwin = 0;
- }
- }
- else {
- numwin = 0;
- }
- break;
- default:
- printf("unknown event: %dn", theEvent.xany.type);
- break;
- }
- }
- return numwin;
- }
- #define RND(val) ((int) ((val) + 0.5))
- /*ARGSUSED*/
- void
- do_hardcopy(prog, info, init_fun, dev_spec, file_or_dev, maxdim,
- ti_fam, ti_size, ax_fam, ax_size, doc_p)
- char *prog; /* Program name for Xdefaults */
- char *info; /* Some state information */
- int (*init_fun) (); /* Hardcopy init function */
- char *dev_spec; /* Device specification (if any) */
- char *file_or_dev; /* Filename or device spec */
- double maxdim; /* Maximum dimension in cm */
- char *ti_fam,
- *ax_fam; /* Font family names */
- double ti_size,
- ax_size; /* Font sizes in points */
- int doc_p; /* Documentation predicate */
- /*
- * This routine resets the function pointers to those specified
- * by `init_fun' and causes a screen redisplay. If `dev_spec'
- * is non-zero, it will be considered a sprintf string with
- * one %s which will be filled in with `file_or_dev' and fed
- * to popen(3) to obtain a stream. Otherwise, `file_or_dev'
- * is considered to be a file and is opened for writing. The
- * resulting stream is fed to the initialization routine for
- * the device.
- */
- {
- LocalWin *curWin = (LocalWin *) info;
- LocalWin thisWin;
- FILE *out_stream;
- char buf[MAXBUFSIZE],
- err[MAXBUFSIZE],
- ierr[ERRBUFSIZE];
- char tilde[MAXBUFSIZE * 10];
- int final_w,
- final_h,
- flags;
- double ratio;
- if (dev_spec) {
- (void) sprintf(buf, dev_spec, file_or_dev);
- out_stream = popen(buf, "w");
- if (!out_stream) {
- sprintf(err, "Unable to issue command:n %sn", buf);
- do_error(err);
- return;
- }
- }
- else {
- tildeExpand(tilde, file_or_dev);
- out_stream = fopen(tilde, "w");
- if (!out_stream) {
- sprintf(err, "Unable to open file `%s'n", tilde);
- do_error(err);
- return;
- }
- }
- if (curWin != (LocalWin *) 0) {
- thisWin = *curWin;
- ratio = ((double) thisWin.dev_info.area_w) /
- ((double) thisWin.dev_info.area_h);
- }
- else
- ratio = 1.0;
- if (thisWin.dev_info.area_w > thisWin.dev_info.area_h) {
- final_w = RND(maxdim * 10000.0 * PM_DBL("Scale"));
- final_h = RND(maxdim / ratio * 10000.0 * PM_DBL("Scale"));
- }
- else {
- final_w = RND(maxdim * ratio * 10000.0 * PM_DBL("Scale"));
- final_h = RND(maxdim * 10000.0 * PM_DBL("Scale"));
- }
- ierr[0] = ' ';
- flags = 0;
- if (doc_p)
- flags |= D_DOCU;
- if ((*init_fun) (out_stream, final_w, final_h, ti_fam, ti_size,
- ax_fam, ax_size, flags, &(thisWin.dev_info), ierr)) {
- DrawWindow(&thisWin);
- if (thisWin.dev_info.xg_end) {
- thisWin.dev_info.xg_end(thisWin.dev_info.user_state);
- }
- }
- else {
- do_error(ierr);
- }
- if (dev_spec) {
- (void) pclose(out_stream);
- }
- else {
- (void) fclose(out_stream);
- }
- }
- static char *
- tildeExpand(out, in)
- char *out; /* Output space for expanded file name */
- char *in; /* Filename with tilde */
- /*
- * This routine expands out a file name passed in `in' and places
- * the expanded version in `out'. It returns `out'.
- */
- {
- char username[50],
- *userPntr;
- struct passwd *userRecord;
- out[0] = ' ';
- /* Skip over the white space in the initial path */
- while ((*in == ' ') ||(*in == 't'))
- in ++;
- /* Tilde? */
- if (in[0] == TILDE) {
- /* Copy user name into 'username' */
- in ++;
- userPntr = &(username[0]);
- while ((*in !=' ') &&(*in !='/')) {
- *(userPntr++) = *(in ++);
- }
- *(userPntr) = ' ';
- /* See if we have to fill in the user name ourselves */
- if (strlen(username) == 0) {
- userRecord = getpwuid(getuid());
- }
- else {
- userRecord = getpwnam(username);
- }
- if (userRecord) {
- /* Found user in passwd file. Concatenate user directory */
- strcat(out, userRecord->pw_dir);
- }
- }
- /* Concantenate remaining portion of file name */
- strcat(out, in);
- return out;
- }
- #define ERR_MSG_SIZE 2048
- /*ARGSUSED*/
- static int
- XErrHandler(disp_ptr, evt)
- Display *disp_ptr;
- XErrorEvent *evt;
- /*
- * Displays a nicely formatted message and core dumps.
- */
- {
- char err_buf[ERR_MSG_SIZE],
- mesg[ERR_MSG_SIZE],
- number[ERR_MSG_SIZE];
- char *mtype = "XlibMessage";
- XGetErrorText(disp_ptr, evt->error_code, err_buf, ERR_MSG_SIZE);
- (void) fprintf(stderr, "X Error: %sn", err_buf);
- XGetErrorDatabaseText(disp_ptr, mtype, "MajorCode",
- "Request Major code %d", mesg, ERR_MSG_SIZE);
- (void) fprintf(stderr, mesg, evt->request_code);
- (void) sprintf(number, "%d", evt->request_code);
- XGetErrorDatabaseText(disp_ptr, "XRequest", number, "", err_buf,
- ERR_MSG_SIZE);
- (void) fprintf(stderr, " (%s)n", err_buf);
- abort();
- }