static void handlekeypressed(Widget w, XtPointer client_data, XEvent *ev, Boolean *continue_dispatch) { XKeyEvent *keyev = & ev->xkey; GRAPH *graph = (GRAPH *) client_data; char text[4]; int nbytes; NG_IGNORE(w); NG_IGNORE(continue_dispatch); nbytes = XLookupString(keyev, text, 4, NULL, NULL); if (!nbytes) return; /* write it */ PushGraphContext(graph); text[nbytes] = '\0'; SetColor(1); DevDrawText(text, keyev->x, graph->absolute.height - keyev->y); /* save it */ SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y); /* warp mouse so user can type in sequence */ XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, keyev->x + XTextWidth(DEVDEP(graph).font, text, nbytes), keyev->y); PopGraphContext(); }
static void resize(Widget w, XtPointer client_data, XEvent *call_data, Boolean *continue_dispatch) { GRAPH *graph = (GRAPH *) client_data; XEvent ev; NG_IGNORE(call_data); NG_IGNORE(continue_dispatch); /* pull out all other exposure events Also, get rid of other StructureNotify events on this window. */ while (XCheckWindowEvent(display, DEVDEP(graph).window, /* ExposureMask | */ StructureNotifyMask, &ev)) ; XClearWindow(display, DEVDEP(graph).window); graph->absolute.width = w->core.width; graph->absolute.height = w->core.height; { GRAPH *tmp = currentgraph; currentgraph = graph; gr_resize(graph); currentgraph = tmp; } }
int X11_SetLinestyle(int linestyleid) { XGCValues values; if (currentgraph->linestyle != linestyleid) { if ((linestyleid == 0 || numdispplanes > 1) && linestyleid != 1) { /* solid if linestyle 0 or if has color, allow only one * dashed linestyle */ values.line_style = LineSolid; } else { values.line_style = LineOnOffDash; } XChangeGC(display, DEVDEP(currentgraph).gc, GCLineStyle, &values); currentgraph->linestyle = linestyleid; XSetDashes(display, DEVDEP(currentgraph).gc, 0, xlinestyles[linestyleid], 4); } return 0; }
void handlekeypressed(Widget w, caddr_t clientdata, caddr_t calldata) { XKeyEvent *keyev = (XKeyPressedEvent *) calldata; GRAPH *graph = (GRAPH *) clientdata; char text[4]; int nbytes; nbytes = XLookupString(keyev, text, 4, NULL, NULL); if (!nbytes) return; /* write it */ PushGraphContext(graph); text[nbytes] = '\0'; SetColor(1); Text(text, keyev->x, graph->absolute.height - keyev->y); /* save it */ SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y); /* warp mouse so user can type in sequence */ XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, keyev->x + XTextWidth(DEVDEP(graph).font, text, nbytes), keyev->y); PopGraphContext(); }
int X11_SetColor(int colorid) { currentgraph->currentcolor = colorid; XSetForeground(display, DEVDEP(currentgraph).gc, DEVDEP(currentgraph).colors[colorid]); return 0; }
int X11_DrawLine(int x1, int y1, int x2, int y2) { if (DEVDEP(currentgraph).isopen) XDrawLine(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x1, currentgraph->absolute.height - y1, x2, currentgraph->absolute.height - y2); return 0; }
int GL_Text(char *text, int x, int y) { /* move to (x, y) */ fprintf(plotfile, "PU;PA %d , %d;", jgmult*(x+xoff+XTADJ), jgmult*(y+yoff+YTADJ)); fprintf(plotfile, "LB %s \x03", text); DEVDEP(currentgraph).lastx = -1; DEVDEP(currentgraph).lasty = -1; return 0; }
void killwin(Widget w, caddr_t client_data, caddr_t call_data) { GRAPH *graph = (GRAPH *) client_data; /* Iplots are done asynchronously */ DEVDEP(graph).isopen = 0; /* MW. Not sure but DestroyGraph might free() to much - try Xt...() first */ XtDestroyWidget(DEVDEP(graph).shell); DestroyGraph(graph->graphid); }
/* devdep initially contains name of output file */ int GL_NewViewport(GRAPH *graph) { hcopygraphid = graph->graphid; if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) { perror((char*) graph->devdep); graph->devdep = NULL; return (1); } if (graph->absolute.width) { /* hardcopying from the screen */ screenflag = 1; /* scale to fit on 8 1/2 square */ } /* reasonable values, used in gr_ for placement */ graph->fontwidth = (int)(fontwidth * scale); /* was 12, p.w.h. */ graph->fontheight = (int)(fontheight * scale); /* was 24, p.w.h. */ graph->absolute.width = dispdev->width; graph->absolute.height = dispdev->height; /* Also done in gr_init, if called . . . */ graph->viewportxoff = 16 * fontwidth; graph->viewportyoff = 8 * fontheight; xoff = XOFF; yoff = YOFF; /* start file off with a % */ fprintf(plotfile, "IN;DF;PA;"); fprintf(plotfile, "SI %f,%f;", tocm*jgmult*fontwidth*scale, tocm*jgmult*fontheight*scale); #ifdef notdef if (!screenflag) #endif graph->devdep = TMALLOC(GLdevdep, 1); DEVDEP(graph).lastlinestyle = -1; DEVDEP(graph).lastx = -1; DEVDEP(graph).lasty = -1; DEVDEP(graph).linecount = 0; graph->linestyle = -1; return 0; }
/* note: x and y are the LOWER left corner of text */ int X11_Text(char *text, int x, int y) { /* We specify text position by lower left corner, so have to adjust for X11's font nonsense. */ if (DEVDEP(currentgraph).isopen) XDrawString(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x, currentgraph->absolute.height - (y + DEVDEP(currentgraph).font->max_bounds.descent), text, (int) strlen(text)); /* note: unlike before, we do not save any text here */ return 0; }
int X11_Clear(void) { if (!noclear) /* hack so exposures look like they're handled nicely */ XClearWindow(display, DEVDEP(currentgraph).window); return 0; }
/* called from postcoms.c In the command 'destroy ac2' Will remove window associated with the plot (e.g. ac2) just before data of the plot are deleted.*/ void RemoveWindow(GRAPH *graph) { if (graph->devdep) { /* Iplots are done asynchronously */ DEVDEP(graph).isopen = 0; /* MW. Not sure but DestroyGraph might free() to much - try Xt...() first */ XtUnmapWidget(DEVDEP(graph).shell); XtDestroyWidget(DEVDEP(graph).shell); XFreeFont(display, DEVDEP(graph).font); XFreeGC(display, DEVDEP(graph).gc); } if (graph == currentgraph) currentgraph = NULL; DestroyGraph(graph->graphid); }
/* call higher gr_redraw routine */ static void redraw(Widget w, XtPointer client_data, XEvent *event, Boolean *continue_dispatch) { GRAPH *graph = (GRAPH *) client_data; XExposeEvent *pev = & event->xexpose; XEvent ev; XRectangle rects[30]; int n = 1; NG_IGNORE(w); NG_IGNORE(continue_dispatch); DEVDEP(graph).isopen = 1; rects[0].x = (Position) pev->x; rects[0].y = (Position) pev->y; rects[0].width = (Dimension) pev->width; rects[0].height = (Dimension) pev->height; /* XXX */ /* pull out all other expose regions that need to be redrawn */ while (n < 30 && XCheckWindowEvent(display, DEVDEP(graph).window, ExposureMask, &ev)) { pev = (XExposeEvent *) &ev; rects[n].x = (Position) pev->x; rects[n].y = (Position) pev->y; rects[n].width = (Dimension) pev->width; rects[n].height = (Dimension) pev->height; n++; } XSetClipRectangles(display, DEVDEP(graph).gc, 0, 0, rects, n, Unsorted); noclear = True; { GRAPH *tmp = currentgraph; currentgraph = graph; gr_redraw(graph); currentgraph = tmp; } noclear = False; XSetClipMask(display, DEVDEP(graph).gc, None); }
void resize(Widget w, caddr_t client_data, caddr_t call_data) { GRAPH *graph = (GRAPH *) client_data; XEvent ev; /* pull out all other exposure events Also, get rid of other StructureNotify events on this window. */ while (XCheckWindowEvent(display, DEVDEP(graph).window, (long) /* ExposureMask | */ StructureNotifyMask, &ev)) ; XClearWindow(display, DEVDEP(graph).window); graph->absolute.width = w->core.width; graph->absolute.height = w->core.height; gr_resize(graph); }
int X11_Arc(int x0, int y0, int radius, double theta, double delta_theta) { int t1, t2; if (0 && !cp_getvar("x11lineararcs", CP_BOOL, NULL)) linear_arc(x0, y0, radius, theta, delta_theta); if (DEVDEP(currentgraph).isopen) { t1 = (int) (64 * (180.0 / M_PI) * theta); t2 = (int) (64 * (180.0 / M_PI) * delta_theta); if (t2 == 0) return 0; XDrawArc(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x0 - radius, currentgraph->absolute.height - radius - y0, (Dimension) (2 * radius), (Dimension) (2 * radius), t1, t2); } return 0; }
/* call higher gr_redraw routine */ void redraw(Widget w, caddr_t client_data, caddr_t call_data) { GRAPH *graph = (GRAPH *) client_data; XExposeEvent *pev = (XExposeEvent *) call_data; XEvent ev; XRectangle rects[30]; int n = 1; DEVDEP(graph).isopen = 1; rects[0].x = pev->x; rects[0].y = pev->y; rects[0].width = pev->width; rects[0].height = pev->height; /* XXX */ /* pull out all other expose regions that need to be redrawn */ while (n < 30 && XCheckWindowEvent(display, DEVDEP(graph).window, (long) ExposureMask, &ev)) { pev = (XExposeEvent *) &ev; rects[n].x = pev->x; rects[n].y = pev->y; rects[n].width = pev->width; rects[n].height = pev->height; n++; } XSetClipRectangles(display, DEVDEP(graph).gc, 0, 0, rects, n, Unsorted); noclear = True; gr_redraw(graph); noclear = False; XSetClipMask(display, DEVDEP(graph).gc, None); }
int GL_Close(void) { /* in case GL_Close is called as part of an abort, w/o having reached GL_NewViewport */ if (plotfile) { if (DEVDEP(currentgraph).lastlinestyle != -1) { DEVDEP(currentgraph).linecount = 0; } fclose(plotfile); plotfile = NULL; } /* In case of hardcopy command destroy the hardcopy graph * and reset currentgraph to graphid 1, if possible */ if (!screenflag) { DestroyGraph(hcopygraphid); currentgraph = FindGraph(1); } return 0; }
int X11_Arc(int x0, int y0, int radius, double theta1, double theta2) { int t1, t2; if (!cp_getvar("x11lineararcs", VT_BOOL, (char *) &t1)) { linear_arc(x0, y0, radius, theta1, theta2); } if (DEVDEP(currentgraph).isopen) { if (theta1 >= theta2) theta2 = 2 * M_PI + theta2; t1 = 64 * (180.0 / M_PI) * theta1; t2 = 64 * (180.0 / M_PI) * theta2 - t1; if (t2 == 0) return 0; XDrawArc(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x0 - radius, currentgraph->absolute.height - radius - y0, 2 * radius, 2 * radius, t1, t2); } return 0; }
/* ARGSUSED */ int GL_Arc(int x0, int y0, int r, double theta, double delta_theta) { int x1, y1, angle; x1 = x0 + (int)(r * cos(theta)); y1 = y0 + (int)(r * sin(theta)); angle = (int)(RAD_TO_DEG * delta_theta); fprintf(plotfile, "PU;PA %d , %d;", jgmult*(x1+xoff+XTADJ), jgmult*(y1+yoff+YTADJ)); fprintf(plotfile, "PD;AA %d , %d, %d;", jgmult*(x0+xoff+XTADJ), jgmult*(y0+yoff+YTADJ), angle); DEVDEP(currentgraph).linecount = 0; return 0; }
int GL_DrawLine(int x1, int y1, int x2, int y2) { /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ if (DEVDEP(currentgraph).linecount == 0 || x1 != DEVDEP(currentgraph).lastx || y1 != DEVDEP(currentgraph).lasty) { fprintf(plotfile, "PU;PA %d , %d ;", jgmult*(x1 + xoff), jgmult*(y1 + yoff)); } if (x1 != x2 || y1 != y2) { fprintf(plotfile, "PD;PA %d , %d ;", jgmult*(x2 + xoff), jgmult*(y2 + yoff)); DEVDEP(currentgraph).linecount += 1; } DEVDEP(currentgraph).lastx = x2; DEVDEP(currentgraph).lasty = y2; DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle; return 0; }
/* should be able to do this by sleight of hand on graph parameters */ static void zoomin(GRAPH *graph) { /* note: need to add circular boxes XXX */ int x0, y0, x1, y1; double fx0, fx1, fy0, fy1, ftemp; char buf[BSIZE_SP]; char buf2[128]; char *t; Window rootwindow, childwindow; int rootx, rooty; unsigned int state; int x, y, upperx, uppery; unsigned width, height; /* open box and get area to zoom in on */ XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x0, &y0, &state); x = x1 = x0 + BOXSIZE; y = y1 = y0 + BOXSIZE; upperx = x0; uppery = y0; width = BOXSIZE; height = BOXSIZE; XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, width, height); XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, x1, y1); while (state & Button3Mask) { if (x != x1 || y != y1) { x1 = x; y1 = y; XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, width, height); upperx = MIN(x1, x0); uppery = MIN(y1, y0); width = (unsigned) ABS(x1 - x0); height = (unsigned) ABS(y1 - y0); XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, width, height); } XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x, &y, &state); } XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, width, height); X_ScreentoData(graph, x0, y0, &fx0, &fy0); X_ScreentoData(graph, x1, y1, &fx1, &fy1); if (fx0 > fx1) { ftemp = fx0; fx0 = fx1; fx1 = ftemp; } if (fy0 > fy1) { ftemp = fy0; fy0 = fy1; fy1 = ftemp; } strncpy(buf2, graph->plotname, sizeof(buf2)); if ((t = strchr(buf2, ':')) != NULL) *t = 0; if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", buf2, graph->commandline, fx0, fx1, fy0, fy1); } else { (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", graph->commandline, fx0, fx1, fy0, fy1); } /* don't use the following if using GNU Readline or BSD EditLine */ #if !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) { wordlist *wl; /* hack for Gordon Jacobs */ /* add to history list if plothistory is set */ if (cp_getvar("plothistory", CP_BOOL, NULL)) { wl = cp_parse(buf); (void) cp_addhistent(cp_event++, wl); } } #endif /* !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) */ (void) cp_evloop(buf); }
static void slopelocation(GRAPH *graph, int x0, int y0) /* initial position of mouse */ { int x1, y1; int x, y; Window rootwindow, childwindow; int rootx, rooty; unsigned int state; double fx0, fx1, fy0, fy1; double angle; x1 = x0; y1 = y0; XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x, &y, &state); XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); while (state & Button1Mask) { if (x != x1 || y != y1) { XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); x1 = x; y1 = y; XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); } XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x, &y, &state); } XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); X_ScreentoData(graph, x0, y0, &fx0, &fy0); X_ScreentoData(graph, x1, y1, &fx1, &fy1); /* print it out */ if (x1 == x0 && y1 == y0) { /* only one location */ fprintf(stdout, "\nx0 = %g, y0 = %g\n", fx0, fy0); if (graph->grid.gridtype == GRID_POLAR || graph->grid.gridtype == GRID_SMITH || graph->grid.gridtype == GRID_SMITHGRID) { angle = RAD_TO_DEG * atan2(fy0, fx0); fprintf(stdout, "r0 = %g, a0 = %g\n", hypot(fx0, fy0), (angle>0)?angle:360.0+angle); } } else { /* need to print info about two points */ fprintf(stdout, "\nx0 = %g, y0 = %g x1 = %g, y1 = %g\n", fx0, fy0, fx1, fy1); fprintf(stdout, "dx = %g, dy = %g\n", fx1-fx0, fy1 - fy0); if (x1 != x0 && y1 != y0) { /* add slope info if both dx and dy are zero, because otherwise either dy/dx or dx/dy is zero, which is uninteresting */ fprintf(stdout, "dy/dx = %g dx/dy = %g\n", (fy1-fy0)/(fx1-fx0), (fx1-fx0)/(fy1-fy0)); } } }
static void initcolors(GRAPH *graph) { int i; static char *colornames[] = { "black", /* white */ "white", "red", "blue", "orange", "green", "pink", "brown", "khaki", "plum", "orchid", "violet", "maroon", "turquoise", "sienna", "coral", "cyan", "magenta", "gold", "yellow", "" }; XColor visualcolor, exactcolor; char buf[BSIZE_SP], colorstring[BSIZE_SP]; int xmaxcolors = NUMCOLORS; /* note: can we get rid of this? */ if (numdispplanes == 1) { /* black and white */ xmaxcolors = 2; DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; if (DEVDEP(graph).colors[0] == WhitePixel(display, DefaultScreen(display))) DEVDEP(graph).colors[1] = BlackPixel(display, DefaultScreen(display)); else DEVDEP(graph).colors[1] = WhitePixel(display, DefaultScreen(display)); } else { if (numdispplanes < NXPLANES) xmaxcolors = 1 << numdispplanes; for (i = 0; i < xmaxcolors; i++) { (void) sprintf(buf, "color%d", i); if (!cp_getvar(buf, CP_STRING, colorstring)) (void) strcpy(colorstring, colornames[i]); if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { (void) sprintf(ErrorMessage, "can't get color %s\n", colorstring); externalerror(ErrorMessage); DEVDEP(graph).colors[i] = i ? BlackPixel(display, DefaultScreen(display)) : WhitePixel(display, DefaultScreen(display)); continue; } DEVDEP(graph).colors[i] = visualcolor.pixel; /* MW. I don't need this, everyone must know what he is doing if (i > 0 && DEVDEP(graph).colors[i] == DEVDEP(graph).view->core.background_pixel) { DEVDEP(graph).colors[i] = DEVDEP(graph).colors[0]; } */ } /* MW. Set Beackgroound here */ XSetWindowBackground(display, DEVDEP(graph).window, DEVDEP(graph).colors[0]); /* if (DEVDEP(graph).colors[0] != DEVDEP(graph).view->core.background_pixel) { DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; } */ } for (i = xmaxcolors; i < NUMCOLORS; i++) { DEVDEP(graph).colors[i] = DEVDEP(graph).colors[i + 1 - xmaxcolors]; } }
/* NewViewport is responsible for filling in graph->viewport */ int X11_NewViewport(GRAPH *graph) { char fontname[513]; /* who knows . . . */ char *p, *q; Cursor cursor; XSetWindowAttributes w_attrs; XGCValues gcvalues; static Arg formargs[ ] = { { XtNleft, (XtArgVal) XtChainLeft }, { XtNresizable, (XtArgVal) TRUE } }; static Arg bboxargs[ ] = { { XtNfromHoriz, (XtArgVal) NULL }, { XtNbottom, (XtArgVal) XtChainTop }, { XtNtop, (XtArgVal) XtChainTop }, { XtNleft, (XtArgVal) XtChainRight }, { XtNright, (XtArgVal) XtChainRight } }; static Arg buttonargs[ ] = { { XtNlabel, (XtArgVal) NULL }, { XtNfromVert, (XtArgVal) NULL }, { XtNbottom, (XtArgVal) XtChainTop }, { XtNtop, (XtArgVal) XtChainTop }, { XtNleft, (XtArgVal) XtRubber }, { XtNright, (XtArgVal) XtRubber }, { XtNresizable, (XtArgVal) TRUE } }; static Arg viewargs[] = { { XtNresizable, (XtArgVal) TRUE }, { XtNwidth, (XtArgVal) 300 }, { XtNheight, (XtArgVal) 300 }, { XtNright, (XtArgVal) XtChainRight } }; int trys; graph->devdep = TMALLOC(X11devdep, 1); /* set up new shell */ DEVDEP(graph).shell = XtCreateApplicationShell ("shell", topLevelShellWidgetClass, NULL, 0); XtVaSetValues(DEVDEP(graph).shell, XtNtitle, graph->plotname, NULL); /* set up form widget */ DEVDEP(graph).form = XtCreateManagedWidget ("form", formWidgetClass, DEVDEP(graph).shell, formargs, XtNumber(formargs)); /* set up viewport */ DEVDEP(graph).view = XtCreateManagedWidget ("viewport", widgetClass, DEVDEP(graph).form, viewargs, XtNumber(viewargs)); XtAddEventHandler(DEVDEP(graph).view, ButtonPressMask, FALSE, handlebuttonev, graph); XtAddEventHandler(DEVDEP(graph).view, KeyPressMask, FALSE, handlekeypressed, graph); XtAddEventHandler(DEVDEP(graph).view, StructureNotifyMask, FALSE, resize, graph); XtAddEventHandler(DEVDEP(graph).view, ExposureMask, FALSE, redraw, graph); /* set up button box */ XtSetArg(bboxargs[1], XtNfromHoriz, DEVDEP(graph).view); DEVDEP(graph).buttonbox = XtCreateManagedWidget ("buttonbox", boxWidgetClass, DEVDEP(graph).form, bboxargs, XtNumber(bboxargs)); /* set up buttons */ XtSetArg(buttonargs[0], XtNlabel, "quit"); XtSetArg(bboxargs[1], XtNfromVert, NULL); DEVDEP(graph).buttons[0] = XtCreateManagedWidget ("quit", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1); XtAddCallback(DEVDEP(graph).buttons[0], XtNcallback, killwin, graph); XtSetArg(buttonargs[0], XtNlabel, "hardcopy"); XtSetArg(bboxargs[1], XtNfromVert, DEVDEP(graph).buttons[0]); DEVDEP(graph).buttons[1] = XtCreateManagedWidget ("hardcopy", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1); XtAddCallback(DEVDEP(graph).buttons[1], XtNcallback, hardcopy, graph); /* set up fonts */ if (!cp_getvar("font", CP_STRING, fontname)) (void) strcpy(fontname, DEF_FONT); for (p = fontname; *p && *p <= ' '; p++) ; if (p != fontname) { for (q = fontname; *p; *q++ = *p++) ; *q = 0; } trys = 1; while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { sprintf(ErrorMessage, "can't open font %s", fontname); strcpy(fontname, "fixed"); if (trys > 1) { internalerror(ErrorMessage); RECOVERNEWVIEWPORT(); return (1); } trys += 1; } graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - DEVDEP(graph).font->min_bounds.lbearing + 1; graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + DEVDEP(graph).font->max_bounds.descent + 1; XtRealizeWidget(DEVDEP(graph).shell); DEVDEP(graph).window = XtWindow(DEVDEP(graph).view); DEVDEP(graph).isopen = 0; w_attrs.bit_gravity = ForgetGravity; XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); /* have to note font and set mask GCFont in XCreateGC, p.w.h. */ gcvalues.font = DEVDEP(graph).font->fid; gcvalues.line_width = MW_LINEWIDTH; gcvalues.cap_style = CapNotLast; gcvalues.function = GXcopy; DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; graph->absolute.ypos = DEVDEP(graph).view->core.y; graph->absolute.width = DEVDEP(graph).view->core.width; graph->absolute.height = DEVDEP(graph).view->core.height; initlinestyles(); initcolors(graph); /* set up cursor */ cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); /* WM_DELETE_WINDOW protocol */ atom_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); atom_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); XtAddEventHandler(DEVDEP(graph).shell, NoEventMask, True, handle_wm_messages, graph); XSetWMProtocols(display, XtWindow(DEVDEP(graph).shell), &atom_wm_delete_window, 1); return (0); }
/* should be able to do this by sleight of hand on graph parameters */ void zoomin(GRAPH *graph) { /* note: need to add circular boxes XXX */ int x0, y0, x1, y1; double fx0, fx1, fy0, fy1, ftemp; char buf[BSIZE_SP]; char buf2[128]; char *t; Window rootwindow, childwindow; int rootx, rooty; unsigned int state; int x, y, upperx, uppery, lowerx, lowery; /* open box and get area to zoom in on */ XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x0, &y0, &state); x = lowerx = x1 = x0 + BOXSIZE; y = lowery = y1 = y0 + BOXSIZE; upperx = x0; uppery = y0; XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, lowerx - upperx, lowery - uppery); /* note: what are src_x, src_y, src_width, and src_height for? XXX */ XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, x1, y1); while (state & Button3Mask) { if (x != x1 || y != y1) { XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, lowerx - upperx, lowery - uppery); x1 = x; y1 = y; /* figure out upper left corner */ /* remember X11's (and X10's) demented coordinate system */ if (y0 < y1) { uppery = y0; upperx = x0; lowery = y1; lowerx = x1; } else { uppery = y1; upperx = x1; lowery = y0; lowerx = x0; } XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, lowerx - upperx, lowery - uppery); } XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, &rootx, &rooty, &x, &y, &state); } XDrawRectangle(display, DEVDEP(graph).window, xorgc, upperx, uppery, lowerx - upperx, lowery - uppery); X_ScreentoData(graph, x0, y0, &fx0, &fy0); X_ScreentoData(graph, x1, y1, &fx1, &fy1); if (fx0 > fx1) { ftemp = fx0; fx0 = fx1; fx1 = ftemp; } if (fy0 > fy1) { ftemp = fy0; fy0 = fy1; fy1 = ftemp; } strncpy(buf2, graph->plotname, sizeof(buf2)); if ((t =strchr(buf2, ':'))) *t = 0; if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", buf2, graph->commandline, fx0, fx1, fy0, fy1); } else { (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", graph->commandline, fx0, fx1, fy0, fy1); } /* don't use the following if using GNU Readline or BSD EditLine */ #if !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) { wordlist *wl; int dummy; /* hack for Gordon Jacobs */ /* add to history list if plothistory is set */ if (cp_getvar("plothistory", VT_BOOL, (char *) &dummy)) { wl = cp_parse(buf); (void) cp_addhistent(cp_event++, wl); } } #endif /* !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) */ (void) cp_evloop(buf); }