Annotation of OpenXM_contrib/pari-2.2/src/graph/plotX.c, Revision 1.2
1.2 ! noro 1: /* $Id: plotX.c,v 1.9 2002/06/09 18:49:11 karim Exp $
1.1 noro 2:
3: Copyright (C) 2000 The PARI group.
4:
5: This file is part of the PARI/GP package.
6:
7: PARI/GP is free software; you can redistribute it and/or modify it under the
8: terms of the GNU General Public License as published by the Free Software
9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10: ANY WARRANTY WHATSOEVER.
11:
12: Check the License for details. You should have received a copy of it, along
13: with the package; see the file 'COPYING'. If not, write to the Free Software
14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15:
16: /*******************************************************************/
17: /* */
18: /* HIGH RESOLUTION PLOT */
19: /* */
20: /*******************************************************************/
1.2 ! noro 21:
! 22: #ifdef BOTH_GNUPLOT_AND_X11 /* The switch support in plotgnuplot */
! 23: # define rectdraw0 X11_rectdraw0
! 24: # define term_set X11_term_set
! 25: # define PARI_get_plot X11_PARI_get_plot
! 26: # define plot_outfile_set X11_plot_outfile_set
! 27: # define set_pointsize X11_set_pointsize
! 28: # define pari_plot pari_X11plot
! 29: #endif
! 30:
1.1 noro 31: #include "pari.h"
32: #include "rect.h"
33: #include "../language/anal.h"
34:
35: extern void free_graph(void);
36:
37: #ifdef HPPA
38: # ifndef __GNUC__
39: typedef char *caddr_t;
40: # endif
41: #endif
42:
43: BEGINEXTERN
44: #include <X11/Xlib.h>
45: #include <X11/Xutil.h>
46: #include <X11/Xos.h>
47: ENDEXTERN
48:
49: static Colormap PARI_Colormap;
50: static XColor *PARI_Colors;
51: static XColor *PARI_ExactColors;
52:
53: static char *PARI_DefaultColors[MAX_COLORS] =
54: {
55: " ",
56: "black", /* Default */
57: "blue", /* Axes */
58: "sienna", /* Odd numbered curves in ploth */
59: "red", /* Curves, or Even numbered curves in ploth */
60: "cornsilk",
61: "grey",
62: "gainsboro",
63: };
64:
65: static void
66: PARI_ColorSetUp(Display *display, char **Colors, int n)
67: {
68: static int init_done = 0;
69: int i;
70:
71: if (init_done) return;
72: init_done=1;
73:
74: PARI_Colormap = DefaultColormap(display, 0);
75: PARI_Colors = (XColor *) gpmalloc((n+1) * sizeof(XColor));
76: PARI_ExactColors = (XColor *) gpmalloc((n+1) * sizeof(XColor));
77: for (i=1; i<n; i++)
78: XAllocNamedColor(display, PARI_Colormap, Colors[i],
79: &PARI_ExactColors[i], &PARI_Colors[i]);
80: }
81:
82: #ifdef SONY
83: typedef int (*XErrorHandler) (
84: # if NeedFunctionPrototypes
85: Display*,
86: XErrorEvent*
87: # endif
88: );
89:
90: extern XErrorHandler XSetErrorHandler (
91: # if NeedFunctionPrototypes
92: XErrorHandler
93: # endif
94: );
95:
96: typedef int (*XIOErrorHandler) (
97: # if NeedFunctionPrototypes
98: Display*
99: # endif
100: );
101:
102: extern XIOErrorHandler XSetIOErrorHandler (
103: # if NeedFunctionPrototypes
104: XIOErrorHandler
105: # endif
106: );
107: #endif
108:
109: /* after fork(), we don't want the child to recover but to exit */
110: static void
111: exiterr(char *str)
112: {
113: term_color(c_ERR);
114: fprintferr("\n *** X fatal error: %s\n",str);
115: term_color(c_NONE); exit(1);
116: }
117:
118: #define MAX_BUF 256
119:
120: static int
121: Xerror(Display *d, XErrorEvent *err) {
122: char buf[MAX_BUF];
123: XGetErrorText(d,err->error_code,buf,MAX_BUF);
124: exiterr(buf); return 0;
125: }
126:
127: static int
128: IOerror(Display *d) {
129: char buf[MAX_BUF];
130: sprintf(buf, "lost display on %s", DisplayString(d));
131: exiterr(buf); return 0;
132: }
133:
134: static char*
135: zmalloc(size_t x)
136: {
137: return x? gpmalloc(x): NULL;
138: }
139:
140: void
141: rectdraw0(long *w, long *x, long *y, long lw, long do_free)
142: {
143: double *ptx,*pty;
144: long *c, shift;
145: long *numpoints[MAX_COLORS],*numtexts[MAX_COLORS];
146: long *xtexts[MAX_COLORS],*ytexts[MAX_COLORS];
147: long rcolcnt[MAX_COLORS][ROt_MAX];
1.2 ! noro 148: long col,i,j,x0,y0,a,b,oldwidth,oldheight;
1.1 noro 149: long rcnt[ROt_MAX+1], hjust, vjust, hgap, vgap, hgapsize, vgapsize;
150: char **texts[MAX_COLORS];
151: PariRect *e;
152: RectObj *p1;
153: double xs=1,ys=1;
154:
155: int screen;
156: Display *display;
157: GC gc;
158: Window win;
159: XEvent event;
160: XSizeHints size_hints;
161: XFontStruct *font_info;
162: XSetWindowAttributes attrib;
163: XPoint *points[MAX_COLORS],**lines[MAX_COLORS];
164: XSegment *seg[MAX_COLORS];
165: XRectangle *rec[MAX_COLORS];
166: Atom wm_delete_window, wm_protocols;
167:
168: if (fork()) return; /* parent process returns */
169:
170: /* child process goes on */
171: freeall(); /* PARI stack isn't needed anymore, keep rectgraph */
1.2 ! noro 172: /* if gnuplot X11 plotting is active, may get SIGPIPE... XXXX Better disable
! 173: * some X callback? */
! 174: os_signal(SIGPIPE, SIG_IGN);
1.1 noro 175: PARI_get_plot(1);
176: display = XOpenDisplay(NULL);
177: font_info = XLoadQueryFont(display, "9x15");
178: if (!font_info) exiterr("cannot open 9x15 font");
179: hgapsize = h_unit; vgapsize = v_unit;
180:
181: XSetErrorHandler(Xerror);
182: XSetIOErrorHandler(IOerror);
183: PARI_ColorSetUp(display,PARI_DefaultColors,MAX_COLORS);
184:
185: for(col=1;col<MAX_COLORS;col++)
186: {
187: rcolcnt[col][ROt_MV]=rcolcnt[col][ROt_PT]=rcolcnt[col][ROt_LN]=0;
188: rcolcnt[col][ROt_BX]=rcolcnt[col][ROt_MP]=rcolcnt[col][ROt_ML]=0;
189: rcolcnt[col][ROt_ST]=rcolcnt[col][ROt_PTT]=rcolcnt[col][ROt_PTS]=rcolcnt[col][ROt_LNT]=0;
190: }
191:
192: for(i=0;i<lw;i++)
193: {
194: e=rectgraph[w[i]]; p1=RHead(e);
195: while(p1)
196: {
197: switch(RoType(p1))
198: {
199: case ROt_MP : rcolcnt[RoCol(p1)][ROt_PT] += RoMPcnt(p1);
200: break; /* Multiple Point */
201: case ROt_PT : /* Point */
202: case ROt_LN : /* Line */
203: case ROt_BX : /* Box */
204: case ROt_ML : /* Multiple lines */
205: case ROt_ST : rcolcnt[RoCol(p1)][RoType(p1)]++;
206: break; /* String */
207: case ROt_MV : /* Move */
208: case ROt_PTT: /* Point type change */
209: case ROt_PTS: /* Point size change */
210: case ROt_LNT: rcnt[RoType(p1)]++; /* Line type change */
211: }
212: p1=RoNext(p1);
213: }
214: }
215: for (col=1; col<MAX_COLORS; col++)
216: {
217: char *m;
218: c = rcolcnt[col];
219: points[col]=(XPoint*)zmalloc(c[ROt_PT]*sizeof(XPoint));
220: seg[col]=(XSegment*)zmalloc(c[ROt_LN]*sizeof(XSegment));
221: rec[col]=(XRectangle*)zmalloc(c[ROt_BX]*sizeof(XRectangle));
222:
223: i = c[ROt_ML]; m = zmalloc(i * (sizeof(long) + sizeof(XPoint*)));
224: numpoints[col]=(long*)m; i *= sizeof(XPoint*);
225: m += i; lines[col]=(XPoint**)m;
226:
227: i = c[ROt_ST]; m = zmalloc(i * (sizeof(char*) + 3*sizeof(long)));
228: texts[col]=(char**)m; i *= sizeof(long);
229: m += i; numtexts[col]=(long*)m;
230: m += i; xtexts[col]=(long*)m;
231: m += i; ytexts[col]=(long*)m;
232:
233: c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0;
234: }
235:
236: screen = DefaultScreen(display);
237: win = XCreateSimpleWindow
238: (display, RootWindow(display, screen), 0, 0, w_width, w_height,
239: 4, BlackPixel(display, screen), WhitePixel(display, screen));
240:
241: size_hints.flags = PPosition | PSize;
242: size_hints.x = 0;
243: size_hints.y = 0;
244: size_hints.width = w_width;
245: size_hints.height = w_height;
246: XSetStandardProperties
247: (display, win, "rectplot", NULL, None, NULL, 0, &size_hints);
248:
249: wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
250: wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
251: XSetWMProtocols(display,win,&wm_delete_window, 1);
252:
253: XSelectInput (display, win,
254: ExposureMask | ButtonPressMask | StructureNotifyMask);
255:
256: /* enable backing-store */
257: attrib.backing_store = Always;
258: attrib.backing_planes = AllPlanes;
259: XChangeWindowAttributes(display,win,CWBackingStore|CWBackingPlanes,&attrib);
260:
261: gc = XCreateGC(display, win, 0, NULL);
262: XSetFont(display, gc, font_info->fid);
263:
1.2 ! noro 264: XClearWindow(display, win);
1.1 noro 265: XMapWindow(display, win);
266: oldwidth = w_width;
1.2 ! noro 267: oldheight = w_height;
1.1 noro 268:
269: for(;;)
270: {
271: XNextEvent(display, &event);
272: switch(event.type)
273: {
274: case ClientMessage:
275: if (event.xclient.message_type != wm_protocols ||
276: (Atom)event.xclient.data.l[0] != wm_delete_window) break;
277: case ButtonPress:
278: case DestroyNotify:
279: XUnloadFont(display,font_info->fid); XFreeGC(display,gc);
280: #define myfree(x) if (x) free(x)
281: for(col=1;col<MAX_COLORS;col++)
282: {
283: myfree(points[col]); myfree(seg[col]); myfree(rec[col]);
284: for(i=0;i<rcolcnt[col][ROt_ML];i++) myfree(lines[col][i]);
285: myfree(numpoints[col]); myfree(texts[col]);
286: }
287: #undef myfree
288: free_graph(); if (do_free) { free(w); free(x); free(y); }
289: XCloseDisplay(display); exit(0);
290:
291: case ConfigureNotify:
292: {
293: int width = event.xconfigure.width;
294: int height = event.xconfigure.height;
295:
296: if (width == oldwidth && height == oldheight) break;
297: oldwidth = width;
1.2 ! noro 298: oldheight = height;
1.1 noro 299:
300: /* recompute scale */
301: xs = ((double)width)/w_width; ys=((double)height)/w_height;
302: }
1.2 ! noro 303: case Expose:
1.1 noro 304: for(i=0; i<lw; i++)
305: {
306: e=rectgraph[w[i]];p1=RHead(e);x0=x[i];y0=y[i];
307: while(p1)
308: {
309: col=RoCol(p1); c=rcolcnt[col];
310: switch(RoType(p1))
311: {
312: case ROt_PT:
313: points[col][c[ROt_PT]].x = DTOL((RoPTx(p1)+x0)*xs);
314: points[col][c[ROt_PT]].y = DTOL((RoPTy(p1)+y0)*ys);
315: c[ROt_PT]++;break;
316: case ROt_LN:
317: seg[col][c[ROt_LN]].x1 = DTOL((RoLNx1(p1)+x0)*xs);
318: seg[col][c[ROt_LN]].y1 = DTOL((RoLNy1(p1)+y0)*ys);
319: seg[col][c[ROt_LN]].x2 = DTOL((RoLNx2(p1)+x0)*xs);
320: seg[col][c[ROt_LN]].y2 = DTOL((RoLNy2(p1)+y0)*ys);
321: c[ROt_LN]++;break;
322: case ROt_BX:
323: a=rec[col][c[ROt_BX]].x = DTOL((RoBXx1(p1)+x0)*xs);
324: b=rec[col][c[ROt_BX]].y = DTOL((RoBXy1(p1)+y0)*ys);
325: rec[col][c[ROt_BX]].width = DTOL((RoBXx2(p1)+x0-a)*xs);
326: rec[col][c[ROt_BX]].height = DTOL((RoBXy2(p1)+y0-b)*ys);
327: c[ROt_BX]++;break;
328: case ROt_MP:
329: ptx = RoMPxs(p1); pty = RoMPys(p1);
330: for(j=0;j<RoMPcnt(p1);j++)
331: {
332: points[col][c[ROt_PT]+j].x = DTOL((ptx[j]+x0)*xs);
333: points[col][c[ROt_PT]+j].y = DTOL((pty[j]+y0)*ys);
334: }
335: c[ROt_PT]+=RoMPcnt(p1);break;
336: case ROt_ML:
337: ptx=RoMLxs(p1); pty=RoMLys(p1);
338: numpoints[col][c[ROt_ML]] = RoMLcnt(p1);
339: lines[col][c[ROt_ML]] =
340: (XPoint*)zmalloc(RoMLcnt(p1)*sizeof(XPoint));
341: for(j=0;j<RoMLcnt(p1);j++)
342: {
343: lines[col][c[ROt_ML]][j].x = DTOL((ptx[j]+x0)*xs);
344: lines[col][c[ROt_ML]][j].y = DTOL((pty[j]+y0)*ys);
345: }
346: c[ROt_ML]++;break;
347: case ROt_ST:
348: hjust = RoSTdir(p1) & RoSTdirHPOS_mask;
349: vjust = RoSTdir(p1) & RoSTdirVPOS_mask;
350: hgap = RoSTdir(p1) & RoSTdirHGAP;
351: if (hgap)
352: hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize;
353: vgap = RoSTdir(p1) & RoSTdirVGAP;
354: if (vgap)
355: vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize;
356: if (vjust != RoSTdirBOTTOM)
357: vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(f_height - 1);
358: texts[col][c[ROt_ST]]=RoSTs(p1);
359: numtexts[col][c[ROt_ST]]=RoSTl(p1);
360: shift = (hjust == RoSTdirLEFT ? 0 :
361: (hjust == RoSTdirRIGHT ? 2 : 1));
362: xtexts[col][c[ROt_ST]]
363: = DTOL(( RoSTx(p1) + x0 + hgap
364: - (strlen(RoSTs(p1)) * pari_plot.fwidth
365: * shift)/2)*xs);
366: ytexts[col][c[ROt_ST]] = DTOL((RoSTy(p1)+y0-vgap/2)*ys);
367: c[ROt_ST]++;break;
368: default: break;
369: }
370: p1=RoNext(p1);
371: }
372: }
373: for(col=1; col<MAX_COLORS; col++)
374: {
375: c = rcolcnt[col];
376: XSetForeground(display, gc, PARI_Colors[col].pixel);
377: if(c[ROt_PT]) XDrawPoints(display,win,gc,points[col],c[ROt_PT],0);
378: if(c[ROt_LN]) XDrawSegments(display,win,gc,seg[col],c[ROt_LN]);
379: if(c[ROt_BX]) XDrawRectangles(display,win,gc,rec[col],c[ROt_BX]);
380: for(i=0;i<c[ROt_ML];i++)
381: XDrawLines(display,win,gc,lines[col][i],numpoints[col][i],0);
382: for(i=0;i<c[ROt_ST];i++)
383: XDrawString(display,win,gc, xtexts[col][i],ytexts[col][i],
384: texts[col][i],numtexts[col][i]);
385:
386: c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0;
387: }
388: }
389: }
390: }
391:
392: void
393: PARI_get_plot(long fatal)
394: {
395: Display *display;
396: int screen;
397:
398: if (pari_plot.init) return;
399: if (!(display = XOpenDisplay(NULL)))
400: {
401: if (fatal) exiterr("no X server");
402: err(talker, "no X server");
403: }
404: screen = DefaultScreen(display);
405: w_width = DisplayWidth(display, screen) - 40;
406: w_height = DisplayHeight(display, screen) - 60;
407: f_height = 15; f_width = 9;
408: h_unit = 5; v_unit = 5;
409: pari_plot.init = 1;
410: XCloseDisplay(display);
411: }
412:
413: long
414: term_set(char *s) { (void)s; return 1; }
415:
416: long
417: plot_outfile_set(char *s) { (void)s; return 1; }
418:
419: void
420: set_pointsize(double d) { (void)d; }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>