📄 x11.c
字号:
currentgraph->colors[colorid]);}X11_Update(){ XSync(display, 0);}X11_Clear(){ if (!noclear) /* hack so exposures look like they're handled nicely */ XClearWindow(display, DEVDEP(currentgraph).window);}voidhandlekeypressed(w, clientdata, calldata)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; 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); } 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]; 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; } if (!eq(plot_cur->pl_typename, graph->plotname)) { (void) sprintf(buf, "setplot %s ; %s xlimit %lg %lg ylimit %lg %lg ; setplot $curplot\n", graph->plotname, graph->commandline, fx0, fx1, fy0, fy1); } else { (void) sprintf(buf, "%s xlimit %lg %lg ylimit %lg %lg\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; XtDestroyWidget(DEVDEP(graph).shell); DestroyGraph(graph->graphid);}/* 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; /* 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; } rects[0].x = pev->x; rects[0].y = pev->y; rects[0].width = pev->width; rects[0].height = pev->height; /* 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. X10 has resize events. X11 blew it. */ while (XCheckWindowEvent(display, DEVDEP(graph).window, (long) ExposureMask | StructureNotifyMask, &ev)) ; graph->absolute.width = w->core.width; graph->absolute.height = w->core.height; gr_resize(graph);}/* 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 BSD 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#ifdef HPUXyoyo: errno = 0;#endif c = getc(fp);#ifdef HPUX if ((c == EOF) && (errno = EINTR)) goto yoyo;#endif return ((int) c);}X11_Input(request, response)REQUEST *request;RESPONSE *response;{ XEvent ev; int nfds, readfds; switch (request->option) { case char_option:#ifdef notdef/* note: check that request->fp has been registered and is the event we get XXX */ /* handle X events first */ do { XtNextEvent(&ev); XtDispatchEvent(&ev); } while (!KEYwaiting); /* dummy typed something */ response->reply.ch = inchar(request->fp); KEYwaiting = FALSE;#endif nfds = ConnectionNumber(display) > fileno(request->fp) ? ConnectionNumber(display) : fileno(request->fp); while (1) {/* X11_Update(); */ /* XtPending should flush the queue */ /* 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 */ do { XtNextEvent(&ev); XtDispatchEvent(&ev); } while (XtPending()); } 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; default: internalerror("unrecognized input type"); response->option = error_option; return; break; }out: response->option = request->option; return;}static X_ScreentoData(graph, x, y, fx, fy)GRAPH *graph;int x,y;double *fx, *fy;{ /* note: figure something out for log grids XXX */ *fx = (x - graph->viewportxoff) * graph->aspectratiox + graph->datawindow.xmin; *fy = ((graph->absolute.height - y) - graph->viewportyoff) * graph->aspectratioy + graph->datawindow.ymin;}#else /* not GI_X11 */int x11_dummy_symbol;/* otherwise, some linkers get upset */#endif /* GI_X11 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -