📄 x11.c
字号:
- (y + DEVDEP(currentgraph).font->max_bounds.descent), text, strlen(text)); /* note: unlike before, we do not save any text here */ return 0;}intX11_DefineColor(int colorid, double red, double green, double blue){ internalerror("X11_DefineColor not implemented."); return 0;}intX11_DefineLinestyle(int linestyleid, int mask){ internalerror("X11_DefineLinestyle not implemented."); return 0;}intX11_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;}intX11_SetColor(int colorid){ currentgraph->currentcolor = colorid; XSetForeground(display, DEVDEP(currentgraph).gc, currentgraph->colors[colorid]); return 0;}intX11_Update(void){ if (X11_Open) XSync(display, 0); return 0;}intX11_Clear(void){ if (!noclear) /* hack so exposures look like they're handled nicely */ XClearWindow(display, DEVDEP(currentgraph).window); return 0;}static voidX_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *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; }}voidslopelocation(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", 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 */voidzoomin(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);}voidhardcopy(Widget w, caddr_t client_data, caddr_t call_data){ lasthardcopy = (GRAPH *) client_data; com_hardcopy(NULL);}voidkillwin(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);}/* call higher gr_redraw routine */voidredraw(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);}voidresize(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);}intX11_Input(REQUEST *request, RESPONSE *response){ XEvent ev; int nfds; fd_set rfds; 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); } /* block on ConnectionNumber and request->fp */ /* PN: added fd_set * casting */ FD_ZERO(&rfds); FD_SET(fileno(request->fp), &rfds); FD_SET(ConnectionNumber(display), &rfds); select (nfds + 1, &rfds, (fd_set *)NULL, (fd_set *)NULL, NULL); /* handle X events first */ if (FD_ISSET (ConnectionNumber(display), &rfds)) { /* handle ALL X events */ while (XtPending()) { XtNextEvent(&ev); XtDispatchEvent(&ev); } } if (FD_ISSET (fileno(request->fp), &rfds)) { 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 1; 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 1; break; }out: if (response) response->option = request->option; return 0;}static voidlinear_arc(int x0, int y0, int radius, double theta1, double theta2) /* x coordinate of center */ /* y coordinate of center */ /* radius of arc */ /* initial angle ( +x axis = 0 rad ) */ /* 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 int x11_dummy_symbol;/* otherwise, some linkers get upset */#endif /* X_DISPLAY_MISSING */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -