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