📄 x11.c
字号:
Widget w;caddr_t clientdata, 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();}# ifdef notdefvoidkeyhandler(clientdata, source, id)caddr_t clientdata;int *source;XtInputId id;{# ifdef notdef KEYwaiting = TRUE;# endif}# endifvoidhandlebuttonev(w, clientdata, calldata)Widget w;caddr_t clientdata, calldata;{ XButtonEvent *buttonev = (XButtonEvent *) calldata; switch (buttonev->button) { case Button1: slopelocation((GRAPH *) clientdata, buttonev->x, buttonev->y); break; case Button3: zoomin((GRAPH *) clientdata); break; }}# ifdef notdefhandlemotionev(w, clientdata, calldata)Widget w;caddr_t clientdata, calldata;{ XMotionEvent *motionev = (XMotionEvent *) calldata; switch}# endifslopelocation(graph, x0, y0)GRAPH *graph;int x0, 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", sqrt( fx0*fx0 + fy0*fy0 ), (angle>0)?angle:(double) 360+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)); } } return;}/* should be able to do this by sleight of hand on graph parameters */zoomin(graph)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; wordlist *wl; int dummy; 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 = index(buf2, ':')) *t = 0; if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf,"setplot %s; %s xlimit %l.20e %l.20e ylimit %l.20e %l.20e; setplot $curplot\n", buf2, graph->commandline, fx0, fx1, fy0, fy1); } else { (void) sprintf(buf, "%s xlimit %le %le ylimit %le %le\n", graph->commandline, fx0, fx1, fy0, fy1); } /* 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); } (void) cp_evloop(buf);}voidhardcopy(w, client_data, call_data) Widget w; caddr_t client_data, call_data;{ lasthardcopy = (GRAPH *) client_data; com_hardcopy(NULL);}voidkillwin(w, client_data, call_data) Widget w; caddr_t client_data, call_data;{ GRAPH *graph = (GRAPH *) client_data; /* Iplots are done asynchronously */ DEVDEP(graph).isopen = 0; DestroyGraph(graph->graphid); XtDestroyWidget(DEVDEP(graph).shell);}/* call higher gr_redraw routine */voidredraw(w, client_data, call_data) Widget w; caddr_t client_data, call_data;{ GRAPH *graph = (GRAPH *) client_data; XExposeEvent *pev = (XExposeEvent *) call_data; XEvent ev; XRectangle rects[30]; int n = 1; DEVDEP(graph).isopen = 1;# ifdef notdef /* if there is a resize, let the resize routine handle the exposures */ if (XCheckWindowEvent(display, DEVDEP(graph).window, (long) StructureNotifyMask, &ev)) { resize(w, client_data, &ev); return; }# endif 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);}voidresize(w, client_data, call_data)Widget w;caddr_t client_data, 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);}# ifdef notdef/* stolen from CP/lexical.c *//* A special 'getc' so that we can deal with ^D properly. There is no way for * stdio to know if we have typed a ^D after some other characters, so * don't use buffering at all... */static int inchar(fp) FILE *fp;{ char c; int i; extern int errno;# ifdef HAS_TERMREAD if (cp_interactive && !cp_nocc) { i = read((int) fileno(fp), &c, 1); if (i == 0) return (EOF); else if (i == -1) { perror("read"); return (EOF); } else return ((int) c); }# endif c = getc(fp); return ((int) c);}# endifX11_Input(request, response) REQUEST *request; RESPONSE *response;{ XEvent ev; int nfds, readfds; switch (request->option) { case char_option: nfds = ConnectionNumber(display) > fileno(request->fp) ? ConnectionNumber(display) : fileno(request->fp); while (1) { /* first read off the queue before doing the select */ while (XtPending()) { XtNextEvent(&ev); XtDispatchEvent(&ev); } readfds = 1 << fileno(request->fp) | 1 << ConnectionNumber(display); /* block on ConnectionNumber and request->fp */ select(nfds + 1, &readfds, (int *) NULL, (int *) NULL, NULL); /* handle X events first */ if (readfds & (1 << ConnectionNumber(display))) { /* handle ALL X events */ while (XtPending()) { XtNextEvent(&ev); XtDispatchEvent(&ev); } } if (readfds & (1 << fileno(request->fp))) { response->reply.ch = inchar(request->fp); goto out; } } break; case click_option: /* let's fake this */ response->reply.graph = lasthardcopy; break; case button_option: /* sit and handle events until get a button selection */ internalerror("button_option not implemented"); response->option = error_option; return; break; case checkup_option: /* first read off the queue before doing the select */ while (XtPending()) { XtNextEvent(&ev); XtDispatchEvent(&ev); } break; default: internalerror("unrecognized input type"); response->option = error_option; return; break; }out: if (response) response->option = request->option; return;}static X_ScreentoData(graph, x, y, fx, fy)GRAPH *graph;int x,y;double *fx, *fy;{ double lmin, lmax; if (graph->grid.gridtype == GRID_XLOG || graph->grid.gridtype == GRID_LOGLOG) { lmin = log10(graph->datawindow.xmin); lmax = log10(graph->datawindow.xmax); *fx = exp(((x - graph->viewportxoff) * (lmax - lmin) / graph->viewport.width + lmin) * M_LN10); } else { *fx = (x - graph->viewportxoff) * graph->aspectratiox + graph->datawindow.xmin; } if (graph->grid.gridtype == GRID_YLOG || graph->grid.gridtype == GRID_LOGLOG) { lmin = log10(graph->datawindow.ymin); lmax = log10(graph->datawindow.ymax); *fy = exp(((graph->absolute.height - y - graph->viewportxoff) * (lmax - lmin) / graph->viewport.height + lmin) * M_LN10); } else { *fy = ((graph->absolute.height - y) - graph->viewportyoff) * graph->aspectratioy + graph->datawindow.ymin; }}/*ARGSUSED*/static voidlinear_arc(x0,y0,radius,theta1,theta2) int x0; /* x coordinate of center */ int y0; /* y coordinate of center */ int radius; /* radius of arc */ double theta1; /* initial angle ( +x axis = 0 rad ) */ double theta2; /* final angle ( +x axis = 0 rad ) */ /* * Notes: * Draws an arc of radius and center at (x0,y0) beginning at * angle theta1 (in rad) and ending at theta2 */{ int x1, y1, x2, y2; int s = 60; double dphi, phi; x2 = x0 + (int) (radius * cos(theta1)); y2 = y0 + (int) (radius * sin(theta1)); while(theta1 >= theta2) theta2 += 2 * M_PI; dphi = (theta2 - theta1) / s; if ((theta1 + dphi) == theta1) { theta2 += 2 * M_PI; dphi = (theta2 - theta1) / s; } for(phi = theta1 + dphi; phi < theta2; phi += dphi) { x1 = x2; y1 = y2; x2 = x0 + (int)(radius * cos(phi)); y2 = y0 + (int)(radius * sin(phi)); X11_DrawLine(x1,y1,x2,y2); } x1 = x2; y1 = y2; x2 = x0 + (int)(radius * cos(theta2)); y2 = y0 + (int)(radius * sin(theta2)); X11_DrawLine(x1,y1,x2,y2);}#else /* not HAS_X11 */int x11_dummy_symbol;/* otherwise, some linkers get upset */#endif /* HAS_X11 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -