Annotation of OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c, Revision 1.23
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.23 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c,v 1.22 2002/08/02 08:59:47 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "parse.h"
52: #include "ox.h"
53: #include "ifplot.h"
54: #include "cursor.h"
1.8 takayama 55: #include <X11/Xaw/MenuButton.h>
56: #include <X11/Xaw/Paned.h>
1.14 noro 57:
1.23 ! noro 58: static Atom wm_delete_window;
! 59:
! 60: static void quit(Widget w, XEvent *ev, String *params,Cardinal *nparams)
! 61: {
! 62: XBell(display,0);
! 63: }
! 64:
1.14 noro 65: /* XXX : these lines are in plotg.c, but ld says they are not defined */
66: #if __DARWIN__
67: int stream;
68:
69: DISPLAY *display;
70: CURSOR normalcur,runningcur,errorcur;
71:
72: #if defined(VISUAL)
73: POINT start_point, end_point;
74: SIZE cansize;
75: #else
76: Window rootwin;
77: GC drawGC,dashGC,hlGC,scaleGC,clearGC,xorGC,colorGC,cdrawGC;
78: XFontStruct *sffs;
79: #endif
80:
81: struct canvas *canvas[MAXCANVAS];
1.19 noro 82: struct canvas *closed_canvas[MAXCANVAS];
1.14 noro 83: struct canvas *current_can;
84: #endif /* __DARWIN__ */
1.1 noro 85:
86: #ifdef ABS
87: #undef ABS
88: #define ABS(a) ((a)>0?(a):-(a))
89: #endif
90:
91: static char *dname;
92: static int depth,scrn;
93:
1.13 noro 94: extern JMP_BUF ox_env;
1.1 noro 95: static Widget toplevel;
96: static XtAppContext app_con;
97:
98: static int busy;
99:
100: static struct PlotResources {
101: Pixel ForePixel,BackPixel,DashPixel;
102: char *ForeName,*BackName,*DashName;
103: Boolean Reverse;
1.18 noro 104: Boolean UpsideDown;
1.1 noro 105: } PlotResources;
106:
107: #define forePixel PlotResources.ForePixel
108: #define backPixel PlotResources.BackPixel
109: #define dashPixel PlotResources.DashPixel
110: #define foreName PlotResources.ForeName
111: #define backName PlotResources.BackName
112: #define dashName PlotResources.DashName
113: #define reverse PlotResources.Reverse
1.18 noro 114: #define upsidedown PlotResources.UpsideDown
1.1 noro 115:
116: Cursor create_cursor();
117:
118: #define blackPixel BlackPixel(display,scrn)
119: #define whitePixel WhitePixel(display,scrn)
120:
121: #define LABELWIDTH 150
122:
123: process_xevent() {
124: XEvent ev;
125:
126: while ( XPending(display) ) {
127: XtAppNextEvent(app_con,&ev);
128: XtDispatchEvent(&ev);
129: }
130: }
131:
132: /* event handlers */
133:
134: static POINT spos,cpos;
135:
136: void press(w,can,ev)
137: Widget w;
138: struct canvas *can;
139: XButtonEvent *ev;
140: {
141: POINT p;
142:
143: switch ( ev->button ) {
144: case Button1:
145: XC(spos) = ev->x; YC(spos) = ev->y; cpos = spos; break;
146: case Button3:
147: XC(p) = ev->x; YC(p) = ev->y; draw_coord(can,&p); break;
148: default:
149: break;
150: }
151: }
152:
153: void motion(w,can,ev)
154: Widget w;
155: struct canvas *can;
156: XMotionEvent *ev;
157: {
158:
159: POINT o,p;
160:
161: if ( ev->state & Button1Mask ) {
162: o = cpos; XC(cpos) = ev->x; YC(cpos) = ev->y;
163: draw_frame(can->window,spos,o,cpos);
164: } else if ( ev->state & Button3Mask ) {
165: XC(p) = ev->x; YC(p) = ev->y;
166: draw_coord(can,p);
167: }
168: }
169:
170: void release(w,can,ev)
171: Widget w;
172: struct canvas *can;
173: XButtonEvent *ev;
174: {
175: POINT e;
176:
177: switch ( ev->button ) {
178: case Button1:
179: e.x = ev->x; e.y = ev->y;
180: draw_frame0(can->window,spos,e);
1.22 noro 181: if ( !busy
182: && can->mode != MODE_INTERACTIVE
183: && can->mode != MODE_POLARPLOT) {
1.1 noro 184: if ( can->mode == MODE_PLOT )
185: plot_resize(can,spos,e);
186: else
187: ifplot_resize(can,spos,e);
188: }
189: break;
190: default:
191: break;
192: }
193: }
194:
195: void structure(w,can,ev)
196: Widget w;
197: struct canvas *can;
198: XEvent *ev;
199: {
200: switch ( ev->xany.type ) {
201: case Expose:
202: if ( !ev->xexpose.count )
203: redraw_canvas(can);
204: break;
205: case ConfigureNotify:
206: redraw_canvas(can); break;
207: default:
208: break;
209: }
210: }
211:
212: static int lindex;
213:
214: void lpress(w,can,ev)
215: Widget w;
216: struct canvas *can;
217: XButtonEvent *ev;
218: {
219: lindex = (can->height-ev->y)/(can->height/can->nzstep);
220: draw_level(can,lindex,hlGC);
221: }
222:
223: void jumpproc(w,can,percent)
224: Widget w;
225: struct canvas *can;
226: float *percent;
227: {
228: int index;
229:
230: index = can->nzstep * (1.0-*percent);
231: if ( index == lindex )
232: return;
233: if ( lindex >= 0 )
234: draw_level(can,lindex,drawGC);
235: lindex = index;
236: draw_level(can,lindex,hlGC);
237: }
238:
239: void jumpproc_m(w,can,percent)
240: Widget w;
241: struct canvas *can;
242: float *percent;
243: {
244: int index;
245:
246: index = can->nzstep * (1.0-*percent);
247: if ( index != lindex ) {
248: draw_level(can,lindex,drawGC);
249: draw_level(can,lindex,hlGC);
250: }
251: }
252:
253: void lrelease(w,can,ev)
254: Widget w;
255: struct canvas *can;
256: XButtonEvent *ev;
257: {
258: draw_level(can,lindex,drawGC); lindex = -1;
259: }
260:
261: void lrelease_m(w,can,ev)
262: Widget w;
263: struct canvas *can;
264: XButtonEvent *ev;
265: {
266: lindex = -1;
267: }
268:
269: draw_level(can,index,gc)
270: struct canvas *can;
271: int index;
272: GC gc;
273: {
274: Pixmap pix;
275: struct pa *pa;
276: int i,len;
277: POINT *p;
278: Arg arg[2];
279: char buf[BUFSIZ];
280:
281: if ( busy || can->wide || index < 0 || index > can->nzstep )
282: return;
283: pix = can->pix; pa = &can->pa[index]; len = pa->length; p = pa->pos;
284: for ( i = 0; i < len; i++ )
285: XDrawPoint(display,pix,gc,p[i].x,p[i].y);
286: sprintf(buf,"level:%g",can->zmin+(can->zmax-can->zmin)*index/can->nzstep);
287: XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
288: XtSetValues(can->level,arg,2);
289: copy_to_canvas(can);
290: }
291:
292: draw_frame(window,spos,opos,epos)
293: Window window;
294: POINT spos,opos,epos;
295: {
296: if ( XC(opos) != XC(epos) || YC(opos) != YC(epos) )
297: draw_frame0(window,spos,opos);
298: draw_frame0(window,spos,epos);
299: }
300:
301: draw_frame0(window,spos,epos)
302: Window window;
303: POINT spos,epos;
304: {
305: int ulx,uly,w,h;
306:
307: ulx = MIN(XC(spos),XC(epos)); uly = MIN(YC(spos),YC(epos));
308: w = ABS(XC(spos)-XC(epos)); h = ABS(YC(spos)-YC(epos));
309: if ( !w || !h )
310: return;
311: XDrawRectangle(display,window,xorGC,ulx,uly,w,h);
312: XFlush(display);
313: }
314:
315: draw_coord(can,pos)
316: struct canvas *can;
317: POINT pos;
318: {
319: char buf[BUFSIZ];
320: Arg arg[2];
321: double x,y,xmin,ymax,dx,dy;
322:
323: if ( can->wide ) {
324: dx = 10*(can->xmax-can->xmin); dy = 10*(can->ymax-can->ymin);
325: xmin = (can->xmax+can->xmin-dx)/2;
326: ymax = (can->ymax+can->ymin+dy)/2;
327: } else {
328: dx = can->xmax-can->xmin; dy = can->ymax-can->ymin;
329: xmin = can->xmin; ymax = can->ymax;
330: }
331: x = xmin+XC(pos)*dx/can->width;
332: y = ymax-YC(pos)*dy/can->height;
333: sprintf(buf,"%s:%g",can->vx?can->vx->name:"horiz",x);
334: XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
335: XtSetValues(can->xcoord,arg,2);
336: sprintf(buf,"%s:%g",can->vy?can->vy->name:"vert",y);
337: XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
338: XtSetValues(can->ycoord,arg,2);
339: }
340:
341: redraw_canvas(can)
342: struct canvas *can;
343: {
344: if ( can->wide )
345: draw_wideframe(can);
346: else
347: copy_to_canvas(can);
348: }
349:
350: search_canvas()
351: {
352: int i;
353:
354: for ( i = 0; i < MAXCANVAS; i++ )
355: if ( !canvas[i] ) {
356: canvas[i] = (struct canvas *)MALLOC(sizeof(struct canvas));
357: canvas[i]->index = i; return i;
358: }
359: }
360:
361: search_active_canvas()
362: {
363: int i;
364:
365: for ( i = 0; i < MAXCANVAS; i++ )
366: if ( canvas[i] )
367: return i;
368: return -1;
369: }
370:
1.19 noro 371: void popup_canvas(index)
372: {
1.20 noro 373: clear_pixmap(canvas[index]);
1.19 noro 374: XtPopup(canvas[index]->shell,XtGrabNone);
1.20 noro 375: copy_to_canvas(canvas[index]);
1.19 noro 376: }
1.4 takayama 377:
1.1 noro 378: void destroy_canvas(w,can,calldata)
379: Widget w;
380: struct canvas *can;
381: XtPointer calldata;
382: {
383: XtPopdown(can->shell);
1.19 noro 384: /* XtDestroyWidget(can->shell); */
1.1 noro 385: XFlush(display);
386: if ( can == current_can ) {
387: reset_busy(can); current_can = 0;
388: }
1.19 noro 389: if ( closed_canvas[can->index] )
390: XtDestroyWidget(closed_canvas[can->index]->shell);
391: closed_canvas[can->index] = can;
1.1 noro 392: canvas[can->index] = 0;
393: }
394:
395: void precise_canvas(w,can,calldata)
396: Widget w;
397: struct canvas *can;
398: XtPointer calldata;
399: {
400: if ( can->precise )
401: can->precise = 0;
402: else
403: can->precise = 1;
404: }
405:
406: void wide_canvas(w,can,calldata)
407: Widget w;
408: struct canvas *can;
409: XtPointer calldata;
410: {
411: if ( can->wide ) {
412: can->wide = 0; copy_to_canvas(can);
413: } else {
414: can->wide = 1; draw_wideframe(can);
415: }
416: }
417:
418: void noaxis_canvas(w,can,calldata)
419: Widget w;
420: struct canvas *can;
421: XtPointer calldata;
422: {
423: if ( can->noaxis )
424: can->noaxis = 0;
425: else
426: can->noaxis = 1;
427: if ( can->wide )
428: draw_wideframe(can);
429: else
430: copy_to_canvas(can);
431: }
432:
433: toggle_button(w,flag)
434: Widget w;
435: int flag;
436: {
437: Arg arg[2];
438:
439: if ( flag ) {
440: XtSetArg(arg[0],XtNforeground,backPixel);
441: XtSetArg(arg[1],XtNbackground,forePixel);
442: } else {
443: XtSetArg(arg[0],XtNforeground,forePixel);
444: XtSetArg(arg[1],XtNbackground,backPixel);
445: }
446: XtSetValues(w,arg,2); XFlush(display);
447: }
448:
449: draw_wideframe(can)
450: struct canvas *can;
451: {
452: struct canvas fakecan;
453: double xmin,xmax,ymin,ymax,xmid,ymid,dx,dy;
454: POINT s,e;
455:
456: fakecan = *can;
457: dx = 10*(can->xmax-can->xmin); dy = 10*(can->ymax-can->ymin);
458: xmid = (can->xmax+can->xmin)/2; ymid = (can->ymax+can->ymin)/2;
459:
460: fakecan.xmin = xmid-dx/2; fakecan.xmax = xmid+dx/2;
461: fakecan.ymin = ymid-dy/2; fakecan.ymax = ymid+dy/2;
462:
463: XFillRectangle(display,can->window,clearGC,
464: 0,0,can->width,can->height);
465: pline(display,&fakecan,can->window);
466: XC(s) = can->width*9/20; YC(s) = can->height*9/20;
467: XC(e) = can->width*11/20; YC(e) = can->height*11/20;
468: draw_frame0(can->window,s,e);
469: }
470:
471: create_popup(parent,name,str,shell,dialog)
472: Widget parent;
473: char *name,*str;
474: Widget *shell,*dialog;
475: {
476: Arg arg[3];
477: Position x,y;
478:
479: XtTranslateCoords(parent,0,0,&x,&y);
480: XtSetArg(arg[0],XtNx,x); XtSetArg(arg[1],XtNy,y);
481: *shell = XtCreatePopupShell(name,transientShellWidgetClass,parent,arg,2);
482: XtSetArg(arg[0],XtNlabel,str);
483: *dialog = XtCreateManagedWidget("dialog",dialogWidgetClass,*shell,arg,1);
484: }
485:
486: warning(can,s)
487: struct canvas *can;
488: char *s;
489: {
490: void popdown_warning();
491: Widget warnshell,warndialog;
492: Position x,y;
493: Arg arg[3];
494:
495: if ( !can->shell )
496: return;
497: create_popup(can->shell,"warning",s,&warnshell,&warndialog);
498: XawDialogAddButton(warndialog,"dismiss",popdown_warning,warnshell);
499: XtPopup(warnshell,XtGrabNone);
1.23 ! noro 500: XSetWMProtocols(display,XtWindow(warnshell),&wm_delete_window,1);
1.1 noro 501: }
502:
503: void popdown_warning(w,client,call)
504: Widget w;
505: XtPointer client,call;
506: {
507: XtPopdown(client); XtDestroyWidget(client);
508: }
509:
510: void show_formula(w,can,calldata)
511: Widget w;
512: struct canvas *can;
513: XtPointer calldata;
514: {
515: void popdown_formula();
516: Widget fshell,fdialog;
517: char buf[BUFSIZ];
518:
519: soutput_init(buf); sprintexpr(CO,(Obj)can->formula);
520: create_popup(can->shell,"formula",buf,&fshell,&fdialog);
521: XawDialogAddButton(fdialog,"dismiss",popdown_formula,w);
522: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.23 ! noro 523: XSetWMProtocols(display,XtWindow(fshell),&wm_delete_window,1);
1.1 noro 524: }
525:
526: void popdown_formula(w,fbutton,call)
527: Widget w,fbutton;
528: XtPointer call;
529: {
530: Widget shell = XtParent(XtParent(w));
531: XtPopdown(shell); XtDestroyWidget(shell);
532: XtSetSensitive(fbutton,True);
533: }
534:
535: #define NormalSelection ButtonPressMask|ButtonReleaseMask|Button1MotionMask|Button3MotionMask|StructureNotifyMask| ExposureMask
536:
537: create_canvas(can)
538: struct canvas *can;
539: {
540: XEvent event;
541: Widget box,frame,commands,
1.4 takayama 542: coords,quit,print,wide,precise,canvas,formula;
1.1 noro 543: Window window;
544: Pixmap pix;
545: int i,width,height;
546: Arg arg[6];
547: char buf[BUFSIZ];
1.8 takayama 548: static void print_canvas();
1.1 noro 549:
550: width = can->width; height = can->height;
551:
1.21 noro 552: sprintf(buf,"%s : %d", can->wname?can->wname:"Plot",can->index);
1.1 noro 553: XtSetArg(arg[0],XtNiconName,buf);
554: can->shell =
555: XtCreatePopupShell("shell",topLevelShellWidgetClass,toplevel,arg,1);
556:
557: XtSetArg(arg[0],XtNhSpace,0);
558: XtSetArg(arg[1],XtNvSpace,0);
559: XtSetArg(arg[2],XtNborderWidth,0);
560: box = XtCreateManagedWidget("box",boxWidgetClass,can->shell,arg,3);
561:
562: frame = XtCreateManagedWidget("form",formWidgetClass,box,NULL,0);
563:
564: XtSetArg(arg[0],XtNorientation,XtorientHorizontal);
565: XtSetArg(arg[1],XtNborderWidth,0);
566: commands = XtCreateManagedWidget("commands",boxWidgetClass,frame,arg,2);
567:
568: quit = XtCreateManagedWidget("quit",commandWidgetClass,commands,NULL,0);
569: XtAddCallback(quit,XtNcallback,destroy_canvas,can);
1.4 takayama 570: print = XtCreateManagedWidget("print",commandWidgetClass,commands,NULL,0);
571: XtAddCallback(print,XtNcallback,print_canvas,can);
1.1 noro 572: can->wideb = wide =
573: XtCreateManagedWidget("wide",toggleWidgetClass,commands,NULL,0);
574: XtAddCallback(wide,XtNcallback,wide_canvas,can);
575: can->preciseb = precise =
576: XtCreateManagedWidget("precise",toggleWidgetClass,commands,NULL,0);
577: XtAddCallback(precise,XtNcallback,precise_canvas,can);
578: formula =
579: XtCreateManagedWidget("formula",commandWidgetClass,commands,NULL,0);
580: XtAddCallback(formula,XtNcallback,show_formula,can);
581: can->noaxisb =
582: XtCreateManagedWidget("noaxis",toggleWidgetClass,commands,NULL,0);
583: XtAddCallback(can->noaxisb,XtNcallback,noaxis_canvas,can);
584:
585: XtSetArg(arg[0],XtNfromVert,commands);
586: XtSetArg(arg[1],XtNwidth,width);
587: XtSetArg(arg[2],XtNheight,height);
588: canvas = XtCreateManagedWidget("canvas",simpleWidgetClass,frame,arg,3);
589:
590: XtSetArg(arg[0],XtNfromVert,canvas);
591: XtSetArg(arg[1],XtNheight,5);
592: XtSetArg(arg[2],XtNwidth,width);
593: XtSetArg(arg[3],XtNorientation,XtorientHorizontal);
594: XtSetArg(arg[4],XtNsensitive,False);
595: can->xdone =
596: XtCreateManagedWidget("xdone",scrollbarWidgetClass,frame,arg,5);
597:
598: XtSetArg(arg[0],XtNfromHoriz,canvas);
599: XtSetArg(arg[1],XtNfromVert,commands);
600: XtSetArg(arg[2],XtNwidth,5);
601: XtSetArg(arg[3],XtNheight,height);
602: XtSetArg(arg[4],XtNorientation,XtorientVertical);
603: XtSetArg(arg[5],XtNsensitive,False);
604: can->ydone =
605: XtCreateManagedWidget("ydone",scrollbarWidgetClass,frame,arg,6);
606:
607: XtSetArg(arg[0],XtNfromVert,can->xdone);
608: XtSetArg(arg[1],XtNorientation,XtorientHorizontal);
609: XtSetArg(arg[2],XtNborderWidth,0);
610: coords = XtCreateManagedWidget("coords",boxWidgetClass,frame,arg,3);
611:
612: XtSetArg(arg[0],XtNwidth,LABELWIDTH);
613: can->xcoord = XtCreateManagedWidget("xcoord",labelWidgetClass,coords,arg,1);
614: XtSetArg(arg[0],XtNwidth,LABELWIDTH);
615: can->ycoord = XtCreateManagedWidget("ycoord",labelWidgetClass,coords,arg,1);
616:
617: XtAddEventHandler(canvas,ButtonPressMask,False,press,can);
618: XtAddEventHandler(canvas,ButtonReleaseMask,False,release,can);
619: XtAddEventHandler(canvas,Button1MotionMask,False,motion,can);
620: XtAddEventHandler(canvas,Button3MotionMask,False,motion,can);
621: XtAddEventHandler(canvas,StructureNotifyMask,False,structure,can);
622: XtAddEventHandler(canvas,ExposureMask,False,structure,can);
623:
624: if ( can->mode == MODE_CONPLOT ) {
625: Widget scale;
626:
627: XtSetArg(arg[0],XtNwidth,LABELWIDTH);
628: can->level = XtCreateManagedWidget("level",labelWidgetClass,
629: commands,arg,1);
630:
631: XtSetArg(arg[0],XtNsensitive,True);
632: XtSetValues(can->ydone,arg,1);
633: if ( depth >= 2 ) {
634: XtAddCallback(can->ydone,XtNjumpProc,jumpproc,can);
635: XtAddEventHandler(can->ydone,ButtonReleaseMask,False,lrelease,can);
636: } else {
637: XtAddCallback(can->ydone,XtNjumpProc,jumpproc_m,can);
638: XtAddEventHandler(can->ydone,ButtonReleaseMask,False,lrelease_m,can);
639: }
640: }
641: if ( can->mode != MODE_IFPLOT || !qpcheck((Obj)can->formula) )
642: XtSetSensitive(precise,False);
643: XtPopup(can->shell,XtGrabNone);
1.23 ! noro 644: XSetWMProtocols(display,XtWindow(can->shell),&wm_delete_window,1);
1.1 noro 645: window = can->window = XtWindow(canvas);
646: pix = can->pix = XCreatePixmap(display,window,width,height,depth);
647: XFillRectangle(display,pix,clearGC,0,0,width,height);
648: XDefineCursor(display,window,normalcur);
649: XFlush(display);
650: current_can = can;
651: }
652:
653: alloc_pixmap(can)
654: struct canvas *can;
655: {
656: can->pix = XCreatePixmap(display,can->window,
657: can->width,can->height,depth);
658: XFillRectangle(display,can->pix,clearGC,0,0,can->width,can->height);
659: }
660:
661: static XrmOptionDescRec options[] = {
1.18 noro 662: {"-upsidedown","*upsidedown",XrmoptionNoArg,"on"},
1.1 noro 663: {"-reverse","*reverse",XrmoptionNoArg,"on"},
664: {"-fg","*foreground",XrmoptionSepArg,NULL},
665: {"-bg","*background",XrmoptionSepArg,NULL},
666: };
667:
668: #define offset(name) XtOffset(struct PlotResources *,name)
669:
670: static XtResource resources[] = {
1.18 noro 671: {"upsidedown","UpsideDown",XtRBoolean,sizeof(Boolean),
672: offset(UpsideDown),XtRBoolean,&upsidedown},
1.1 noro 673: {"reverse","Reverse",XtRBoolean,sizeof(Boolean),
674: offset(Reverse),XtRBoolean,&reverse},
675: {"foreground","Foreground",XtRString,sizeof(char *),
676: offset(ForeName),XtRString,NULL},
677: {"foreground","Foreground",XtRPixel,sizeof(Pixel),
678: offset(ForePixel),XtRPixel,(XtPointer)&forePixel},
679: {"background","Background",XtRString,sizeof(char *),
680: offset(BackName),XtRString,NULL},
681: {"background","Background",XtRPixel,sizeof(Pixel),
682: offset(BackPixel),XtRPixel,(XtPointer)&backPixel},
683: {"dash","Dash",XtRString,sizeof(char *),
684: offset(DashName),XtRString,NULL},
685: {"dash","Dash",XtRPixel,sizeof(Pixel),
686: offset(DashPixel),XtRPixel,(XtPointer)&dashPixel},
687: };
688:
1.12 noro 689: int init_plot_display(argc,argv)
1.1 noro 690: int argc;
691: char **argv;
692: {
693: int ac;
694: char **av;
695: unsigned int tmp;
696:
697: for ( ac = argc, av = argv; ac; ac--, av++ )
1.12 noro 698: if ( !strcmp(*av,"nox") )
699: return 0;
700: else if ( index(*av,':') )
1.1 noro 701: dname = *av;
702: XtToolkitInitialize();
703: app_con = XtCreateApplicationContext();
704: display = XtOpenDisplay(app_con,dname,"plot","Plot",
705: options,XtNumber(options),&argc,argv);
706: if ( !display ) {
707: fprintf(stderr,"Can't open display\n");
1.12 noro 708: return 0;
1.1 noro 709: }
710: toplevel = XtAppCreateShell(0,"Plot",applicationShellWidgetClass,
711: display,0,0);
712:
713: forePixel = blackPixel; backPixel = whitePixel;
714: dashPixel = blackPixel;
715: XtGetApplicationResources(toplevel,&PlotResources,
716: resources,XtNumber(resources),NULL,0);
717: display = XtDisplay(toplevel);
718: scrn = DefaultScreen(display);
719: depth = DefaultDepth(display,scrn);
720: rootwin = RootWindow(display,scrn);
721:
1.23 ! noro 722: /* for handling DELETE message */
! 723: wm_delete_window = XInternAtom(display,"WM_DELETE_WINDOW",False);
! 724: XtOverrideTranslations(toplevel,
! 725: XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()"));
! 726:
1.1 noro 727: if ( reverse ) {
728: tmp = forePixel; forePixel = backPixel; backPixel = tmp;
729: }
730:
731: create_gc();
732: create_font();
733: create_cursors();
1.12 noro 734: return 1;
1.1 noro 735: }
736:
737: static char *scalefont = "*-8-80-*";
738:
739: create_font() {
740: Font sfid;
741:
742: sfid = XLoadFont(display,scalefont);
743: sffs = XQueryFont(display,sfid);
744: XSetFont(display,scaleGC,sfid);
745: }
746:
747: create_gc() {
748: static XColor color = {0,0x0,0x0,0x0,DoRed|DoGreen|DoBlue,0};
749: int i,b,step;
750:
751: drawGC = XCreateGC(display,rootwin,0,NULL);
752: dashGC = XCreateGC(display,rootwin,0,NULL);
753: hlGC = XCreateGC(display,rootwin,0,NULL);
754: clearGC = XCreateGC(display,rootwin,0,NULL);
755: scaleGC = XCreateGC(display,rootwin,0,NULL);
756: xorGC = XCreateGC(display,rootwin,0,NULL);
757: colorGC = XCreateGC(display,rootwin,0,NULL);
1.11 noro 758: cdrawGC = XCreateGC(display,rootwin,0,NULL);
1.1 noro 759: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,drawGC);
760: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,dashGC);
761: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,clearGC);
762: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,scaleGC);
763: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,xorGC);
764: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,colorGC);
1.11 noro 765: XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,cdrawGC);
1.1 noro 766: XSetForeground(display,drawGC,forePixel);
767: XSetForeground(display,scaleGC,forePixel);
768: XSetForeground(display,clearGC,backPixel);
769: XSetForeground(display,xorGC,forePixel^backPixel);
770: XSetFunction(display,xorGC,GXxor);
771: XSetForeground(display,dashGC,dashPixel);
772: XSetLineAttributes(display,dashGC,1,LineOnOffDash,CapButt,JoinRound);
773:
774: color.red = color.green = color.blue = 0xffff/2;
775: XAllocColor(display,DefaultColormap(display,scrn),&color);
776: XSetForeground(display,hlGC,color.pixel);
777: color.red = 0xffff; color.green = color.blue = 0;
778: XAllocColor(display,DefaultColormap(display,scrn),&color);
779: XSetForeground(display,colorGC,color.pixel);
1.11 noro 780: }
781:
782: set_drawcolor(c)
783: unsigned int c;
784: {
785: XColor color = {0,0x0,0x0,0x0,DoRed|DoGreen|DoBlue,0};
786:
787: color.red = (c&0xff0000)>>8;
788: color.green = (c&0xff00);
789: color.blue = (c&0xff)<<8;
790: XAllocColor(display,DefaultColormap(display,scrn),&color);
791: XSetForeground(display,cdrawGC,color.pixel);
1.1 noro 792: }
793:
794: create_cursors() {
795: static XColor fg = {0, 0x0, 0x0, 0x0,DoRed|DoGreen|DoBlue,0};
796: static XColor bg = {0, 0xffff, 0xffff, 0xffff,DoRed|DoGreen|DoBlue,0};
797:
798: XAllocColor(display,DefaultColormap(display,scrn),&fg);
799: XAllocColor(display,DefaultColormap(display,scrn),&bg);
800: normalcur = create_cursor(h_bits,h_m_bits,h_width,h_height,
801: h_x_hot,h_y_hot,&fg,&bg);
802: runningcur = create_cursor(ht_bits,ht_m_bits,ht_width,ht_height,
803: ht_width/2,ht_height/2,&fg,&bg);
804: errorcur = create_cursor(m_bits,m_m_bits,m_width,m_height,
805: m_width/2,m_height/2,&fg,&bg);
806: }
807:
808: Cursor create_cursor(image,mask,width,height,xhot,yhot,fg,bg)
809: char *image,*mask;
810: int width,height,xhot,yhot;
811: XColor *fg,*bg;
812: {
813: Pixmap ipix,mpix;
814:
815: ipix = XCreateBitmapFromData(display,rootwin,image,width,height);
816: mpix = XCreateBitmapFromData(display,rootwin,mask,width,height);
817: return XCreatePixmapCursor(display,ipix,mpix,fg,bg,xhot,yhot);
818: }
819:
820: copy_to_canvas(can)
821: struct canvas *can;
822: {
823: if ( display ) {
824: XCopyArea(display,can->pix,can->window,
825: drawGC,0,0,can->width,can->height,0,0);
826: pline(display,can,can->window);
827: XFlush(display);
828: }
829: }
830:
831: copy_subimage(subcan,can,pos)
832: struct canvas *subcan,*can;
833: XPoint pos;
834: {
835: if ( display ) {
836: XCopyArea(display,subcan->pix,can->pix,
837: drawGC,0,0,subcan->width,subcan->height,pos.x,pos.y);
838: XFlush(display);
839: }
840: }
841:
842: #include <signal.h>
843: #include <fcntl.h>
844:
845: set_selection() {
846: if ( current_can ) {
847: XSelectInput(display,current_can->window,0);
848: XFlush(display);
849: }
850: }
851:
852: reset_selection() {
853: if ( current_can ) {
854: XSelectInput(display,current_can->window,NormalSelection);
855: XFlush(display);
856: }
857: }
858:
859: set_busy(can)
860: struct canvas *can;
861: {
862: busy = 1;
863: XtSetSensitive(can->wideb,False);
864: XtSetSensitive(can->preciseb,False);
865: XtSetSensitive(can->noaxisb,False);
866: XFlush(display);
867: }
868:
869: reset_busy(can)
870: struct canvas *can;
871: {
872: busy = 0;
873: if ( can->window ) {
874: XtSetSensitive(can->wideb,True);
875: XtSetSensitive(can->noaxisb,True);
876: if ( can->mode == MODE_IFPLOT && qpcheck((Obj)can->formula) )
877: XtSetSensitive(can->preciseb,True);
878: XFlush(display);
879: }
880: }
881:
882: reset_current_computation()
883: {
884: if ( current_can ) {
885: reset_selection(); reset_busy(current_can);
886: define_cursor(current_can->window,normalcur);
887: }
1.8 takayama 888: }
889:
890: static struct canvas *Can;
891: /* void print_canvas(Widget w,struct canvas *can, XtPointer calldata); */
892: static void output_to_file(Widget , XtPointer, XtPointer );
893: static void output_to_ps_printer(Widget , XtPointer, XtPointer );
894: static void cancel_output_to_file(Widget , XtPointer,XtPointer);
895: static void generate_psfile(struct canvas *can, FILE *fp);
896: static void set_printing_method(Widget,XtPointer,XtPointer);
897: static void method_is_not_available();
898: static Widget PrintDialog;
899: static Widget PrintDialog_lp;
900: static Widget W;
901: static char *Fname = NULL;
902: static char *PrinterName = NULL;
903: #define PRINTING_METHOD_BITMAP 0
904: #define PRINTING_METHOD_VECTOR 1
905: static int PrintingMethod = PRINTING_METHOD_BITMAP;
906: static String Printing_methods[]={
907: "bitMap","vector",
908: };
909: static int N_printing_methods = 2;
910:
911: /*
912: static Widget create_printing_method_bar(Widget parent) {
913: Widget panel, button;
914: int i,n;
915: Arg wargs[1];
916: panel = XtCreateManagedWidget("printing methods",panedWidgetClass,
917: parent,NULL,0);
918: for (i=0; i<N_printing_methods; i++) {
919: button = XtCreateManagedWidget(Printing_methods[i],menuButtonWidgetClass,
920: panel,NULL,0);
921: fprintf(stderr,"button=%x\n",(int) button);
922: XtAddCallback(button,XtNcallback,set_printing_method,(XtPointer) i);
923: }
924: return(panel);
925: }
926: */
927:
928:
929: static void print_canvas(w,can,calldata)
930: Widget w;
931: struct canvas *can;
932: XtPointer calldata;
933: {
934: Widget fshell,fdialog;
935: extern struct canvas *Can;
936: extern Widget W;
937: Widget entry;
938: int i;
939: Arg arg[1];
940: static void output_to_printer();
941: static void print_canvas_to_file();
942: static void printing_method();
943:
944: W = w;
945: Can = can;
946: create_popup(can->shell,"Print/Output PS file","",&fshell,&fdialog);
947: XawDialogAddButton(fdialog,"print",output_to_printer,w);
948: XawDialogAddButton(fdialog,"output PS file",print_canvas_to_file,w);
949: XawDialogAddButton(fdialog,"method",printing_method,w);
950: XawDialogAddButton(fdialog,"dismiss",cancel_output_to_file,w);
951: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.23 ! noro 952: XSetWMProtocols(display,XtWindow(fshell),&wm_delete_window,1);
1.8 takayama 953: }
954:
955: static void set_printing_method(Widget w,XtPointer number,XtPointer call_data) {
956: Widget shell;
957: extern int PrintingMethod;
958: PrintingMethod = (int) number;
959: fprintf(stderr,"PrintingMethod=%d\n",number);
960: shell = XtParent(XtParent(w));
961: XtPopdown(shell); XtDestroyWidget(shell);
962: }
963:
964: static void printing_method(w,can,calldata)
965: Widget w;
966: struct canvas *can;
967: XtPointer calldata;
968: {
969: Arg arg[10];
970: int i,n;
971: Widget fshell,fdialog;
972: extern struct canvas *Can;
973: extern int PrintingMethod;
974:
975: w = W;
976: can = Can;
977: create_popup(can->shell,"Printing method",Printing_methods[PrintingMethod],
978: &fshell,&fdialog);
979: n = 0;
980: XtSetArg(arg[n], XtNlabel, "Method: "); n++;
981: XtSetArg(arg[n], XtNvalue, Printing_methods[PrintingMethod]); n++;
982: XtSetValues(fdialog,arg,n);
983: for (i=0; i<N_printing_methods; i++) {
984: XawDialogAddButton(fdialog,Printing_methods[i],set_printing_method,(XtPointer) i);
985: }
986: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.23 ! noro 987: XSetWMProtocols(display,XtWindow(fshell),&wm_delete_window,1);
1.8 takayama 988: }
989: static void print_canvas_to_file(w,can,calldata)
990: Widget w;
991: struct canvas *can;
992: XtPointer calldata;
993: {
994: FILE *fp;
995: Arg arg[10];
996: int n;
997: static char *psfile = NULL;
998: Widget fshell,fdialog;
999: extern struct canvas *Can;
1000: extern Widget PrintDialog;
1001: extern char *Fname;
1002:
1003: w = W;
1004: can = Can;
1005: if (psfile == NULL || Fname == NULL) psfile = "ox_plot.eps";
1006: else psfile = Fname;
1007: create_popup(can->shell,"Output as PS file",psfile,&fshell,&fdialog);
1008: n = 0;
1009: XtSetArg(arg[n], XtNlabel, "File : "); n++;
1010: XtSetArg(arg[n], XtNvalue, psfile); n++;
1011: XtSetValues(fdialog,arg,n);
1012: XawDialogAddButton(fdialog,"output to file",output_to_file,w);
1013: XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
1014: PrintDialog = fdialog;
1015: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.23 ! noro 1016: XSetWMProtocols(display,XtWindow(fshell),&wm_delete_window,1);
1.8 takayama 1017: }
1018: static void output_to_printer(w,can,calldata)
1019: Widget w;
1020: struct canvas *can;
1021: XtPointer calldata;
1022: {
1023: FILE *fp;
1024: Arg arg[10];
1025: int n;
1026: static char *psfile = NULL;
1027: Widget fshell,fdialog;
1028: extern struct canvas *Can;
1029: extern Widget PrintDialog_lp;
1030: extern char *PrinterName;
1031:
1032: w = W;
1033: can = Can;
1034: if (psfile == NULL || PrinterName == NULL) psfile = "lp";
1035: else psfile = PrinterName;
1036: create_popup(can->shell,"Output PS file to printer",psfile,&fshell,&fdialog);
1037: n = 0;
1038: XtSetArg(arg[n], XtNlabel, "PS Printer Name : "); n++;
1039: XtSetArg(arg[n], XtNvalue, psfile); n++;
1040: XtSetValues(fdialog,arg,n);
1041: XawDialogAddButton(fdialog,"output to PS printer",output_to_ps_printer,w);
1042: XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
1043: PrintDialog_lp = fdialog;
1044: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.23 ! noro 1045: XSetWMProtocols(display,XtWindow(fshell),&wm_delete_window,1);
1.8 takayama 1046: }
1047:
1048: static void cancel_output_to_file(w,fbutton,call)
1049: Widget w;
1050: XtPointer fbutton, call;
1051: {
1052: Widget shell = XtParent(XtParent(w));
1053: XtPopdown(shell); XtDestroyWidget(shell);
1054: XtSetSensitive(fbutton,True);
1055: }
1056:
1057: static void output_to_file(w,fbutton,call)
1058: Widget w;
1059: XtPointer fbutton, call;
1060: {
1061: char *fname;
1062: FILE *fp;
1063: int i;
1064: char *m;
1065: extern struct canvas *Can;
1066: extern Widget PrintDialog;
1067: extern int PrintingMethod;
1068: Widget shell = XtParent(XtParent(w));
1069:
1070: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1071: }else{
1072: method_is_not_available();
1073: XtPopdown(shell); XtDestroyWidget(shell);
1074: XtSetSensitive(fbutton,True);
1075: return;
1076: }
1077:
1078: fname = XawDialogGetValueString(PrintDialog);
1079: Fname = (char *)malloc(sizeof(char)*strlen(fname)+1);
1080: strcpy(Fname,fname);
1081: for (i=0; i<strlen(Fname); i++) {
1082: if (Fname[i] == 0xd || Fname[i] == 0xa) {
1083: Fname[i] = 0; break;
1084: }
1085: }
1086: fprintf(stderr,"fname=%s\n",Fname); fflush(NULL);
1087: fp = fopen(Fname,"w");
1088: if (fp == NULL) {
1089: warning(Can,"Could not open the output file.");
1090: }else{
1091: generate_psfile(Can,fp);
1092: fclose(fp);
1093: }
1094:
1095: XtPopdown(shell); XtDestroyWidget(shell);
1096: XtSetSensitive(fbutton,True);
1097: }
1098:
1099: static void output_to_ps_printer(w,fbutton,call)
1100: Widget w;
1101: XtPointer fbutton, call;
1102: {
1103: char *printerName;
1104: FILE *fp;
1105: extern struct canvas *Can;
1106: extern Widget PrintDialog_lp;
1107: char fname[256];
1108: char cmd[512];
1109: static int id = 0;
1110: int i;
1111: Widget shell = XtParent(XtParent(w));
1112:
1113: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1114: }else{
1115: method_is_not_available();
1116: XtPopdown(shell); XtDestroyWidget(shell);
1117: XtSetSensitive(fbutton,True);
1118: return;
1119: }
1120:
1121: sprintf(fname,"/tmp/ox_plot_%d.eps",(int) getpid(),id++);
1122:
1123: printerName = XawDialogGetValueString(PrintDialog_lp);
1124: PrinterName = (char *)malloc(sizeof(char)*strlen(printerName)+1);
1125: strcpy(PrinterName,printerName);
1126: for (i=0; i<strlen(PrinterName); i++) {
1127: if (PrinterName[i] == 0xd || PrinterName[i] == 0xa) {
1128: PrinterName[i] = 0; break;
1129: }
1130: }
1131: fprintf(stderr,"printerName=%s\n",PrinterName); fflush(NULL);
1132: fp = fopen(fname,"w");
1133: if (fp == NULL) {
1134: warning(Can,"Could not open the output file.");
1135: }else{
1136: generate_psfile(Can,fp);
1137: fclose(fp);
1138: }
1139:
1140: sprintf(cmd,"lpr -P%s %s",PrinterName,fname);
1141: if (system(cmd)) {
1142: warning(Can,"Unknown printer?");
1143: }
1144: sprintf(cmd,"rm -f %s",fname);
1145: system(cmd);
1146: XtPopdown(shell); XtDestroyWidget(shell);
1147: XtSetSensitive(fbutton,True);
1148: }
1149:
1150:
1151: /* test sequence
1152: ox_launch(0,"ox_plot");
1153: ifplot(x^2-y^3);
1154: drawcircle(0,0,100,0,0);
1155: */
1.15 takayama 1156: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
1157: struct xcolorForPS **tableOfxcolorForPS);
1158:
1.8 takayama 1159: static void generate_psfile(can,fp)
1160: struct canvas *can;
1161: FILE *fp;
1162: {
1163: int x,y;
1164: XImage *image;
1165: int color[1];
1166: int colorSize = 1;
1167: char *m;
1.15 takayama 1168: struct xcolorForPS *tableOfxcolorForPS;
1.8 takayama 1169: extern int PrintingMethod;
1170: fprintf(stderr,"generate_psfile\n");
1171: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1172: if ( display ) {
1173: fprintf(stderr,"generate_psfile: output to a file.\n");
1174: image = XGetImage(display,can->pix,
1175: 0,0,can->width,can->height,-1,ZPixmap);
1.15 takayama 1176: colorSize =
1177: getColorSizeOfImageForPS(can->width,can->height,image,&tableOfxcolorForPS);
1178: color[0] = 0; /* black line */
1.18 noro 1179: generatePS_from_image(fp,image,can->width,can->height,color,colorSize,can,tableOfxcolorForPS,upsidedown);
1.8 takayama 1180: }else{
1181: fprintf(stderr,"Cannot print on this system\n");
1182: }
1183: }else{
1184: method_is_not_available();
1185: }
1186: fflush(NULL);
1187: }
1188:
1189: static void method_is_not_available() {
1190: char *m;
1191: #define MSG1 "Printing method \""
1192: #define MSG2 "\" is not available for this picture."
1193: m = (char *)malloc(strlen(MSG1)+strlen(MSG2)+strlen(Printing_methods[PrintingMethod])+1);
1194: strcpy(m,MSG1);
1195: strcat(m,Printing_methods[PrintingMethod]);
1196: strcat(m,MSG2);
1197: warning(Can,m);
1.9 noro 1198: }
1199:
1200: clear_pixmap(can)
1201: struct canvas *can;
1202: {
1203: XFillRectangle(display,can->pix,clearGC,0,0,can->width,can->height);
1204: XFlush(display);
1.1 noro 1205: }
1.15 takayama 1206:
1207: /*
1208: The following functions are used to generate color postscript file.
1209: */
1210: /* In order to count colorSize, binary tree (sm_btree) is used. */
1211: static struct sm_btree *sm_newNode(unsigned long v);
1212: static int sm_insert(struct sm_btree *node,unsigned long v);
1213: static int sm_count(struct sm_btree *rootp);
1.17 takayama 1214:
1.15 takayama 1215: struct sm_btree {
1216: unsigned long p;
1217: struct sm_btree * left;
1218: struct sm_btree * right;
1219: };
1220: static struct sm_btree *sm_newNode(unsigned long v) {
1221: struct sm_btree * n;
1222: n = (struct sm_btree *)MALLOC(sizeof(struct sm_btree));
1223: if (n == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
1224: n->p = v;
1225: n->left = NULL;
1226: n->right = NULL;
1227: return n;
1228: }
1229: static int sm_insert(struct sm_btree *node,unsigned long v)
1230: {
1231: if (node->p == v) return;
1232: if (node->p > v) {
1233: if (node->left == NULL) {
1234: node->left = sm_newNode(v);
1235: return;
1236: }
1237: sm_insert(node->left,v);
1238: }
1239: if (node->p < v) {
1240: if (node->right == NULL) {
1241: node->right = sm_newNode(v);
1242: return;
1243: }
1244: sm_insert(node->right,v);
1245: }
1246: }
1247: static int sm_count(struct sm_btree *rootp)
1248: {
1249: if (rootp == NULL) return 0;
1250: return (1+sm_count(rootp->left)+sm_count(rootp->right));
1251: }
1252:
1.16 takayama 1253: static int setTableOfxcolorForPS(struct sm_btree *rootp,
1254: struct xcolorForPS *table,int k,int size)
1255: {
1256: int m;
1257: m = k;
1258: if (rootp == NULL) return;
1259: if (k >= size) {
1260: warning(Can,"internal error of setTableOfxcolorForPS");
1261: }
1262: if (rootp->left != NULL) {
1263: m = setTableOfxcolorForPS(rootp->left,table,k,size);
1264: }
1265:
1266: (table[m]).pixel = rootp->p;
1267: m++;
1268: if (rootp->right != NULL) {
1269: m = setTableOfxcolorForPS(rootp->right,table,m,size);
1270: }
1271: return m;
1272: }
1273:
1274:
1.15 takayama 1275: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
1276: struct xcolorForPS **tableOfxcolorForPS)
1277: {
1278: int x,y;
1279: int size;
1280: struct sm_btree root;
1281: struct xcolorForPS *table;
1.16 takayama 1282: XStandardColormap scm;
1283: Colormap cm;
1284: XColor color;
1285: XColor white;
1286: int screen,i;
1287:
1.15 takayama 1288: root.p = 0;
1289: root.left = NULL; root.right=NULL;
1290: /* get color size */
1291: for (x=0; x<xsize; x++) {
1292: for (y=0; y<ysize; y++) {
1293: sm_insert(&root,XGetPixel(image,x,y));
1294: }
1295: }
1296: size=sm_count(&root);
1297:
1298: table = (struct xcolorForPS *)MALLOC((size+1)*sizeof(struct xcolorForPS));
1299: if (table == NULL) {
1300: fprintf(stderr,"No more memory in getColorSizeOfImageForPS.\n");
1301: return 0;
1302: }
1303: /* Set rgb values standing for the pixel values.
1304: */
1.16 takayama 1305: if (setTableOfxcolorForPS(&root,table,0,size) != size) {
1306: warning(Can,"internal error.");
1307: return ;
1308: }
1309:
1310: screen = DefaultScreen(display);
1311: cm = DefaultColormap(display,screen);
1312: /* BUG: it does not work.
1313: if (!XGetStandardColormap(display,RootWindow(display,DefaultScreen(display)),&scm,XA_RGB_DEFAULT_MAP)) {
1314: warning(Can,"failed to open the X Standard Colormap.");
1315: scm.red_max = 0xffff;
1316: scm.green_max = 0xffff;
1317: scm.blue_max = 0xffff;
1318: }
1319: */
1320: /* Set by hand. */
1321: scm.red_max = 0xffff;
1322: scm.green_max = 0xffff;
1323: scm.blue_max = 0xffff;
1324: XParseColor(display,cm,"White",&white);
1325: for (i=0; i<size; i++) {
1326: color.pixel=(table[i]).pixel;
1327: /*
1328: {
1329: char s[254];
1330: sprintf(s,"%ld",color.pixel);
1331: warning(Can,s);
1332: }
1333: */
1334: XQueryColor(display,cm,&color);
1335: (table[i]).r = ((double) color.red)/((double) scm.red_max);
1336: (table[i]).g = ((double) color.green)/((double) scm.green_max);
1337: (table[i]).b = ((double) color.blue)/((double) scm.blue_max);
1338: if ((table[i]).r > 1.0) (table[i]).r = 1.0;
1339: if ((table[i]).g > 1.0) (table[i]).g = 1.0;
1340: if ((table[i]).b > 1.0) (table[i]).b = 1.0;
1341: if (color.red == white.red && color.green == white.green
1342: && color.blue == white.blue) {
1343: (table[i]).print = 0;
1344: }else{
1345: (table[i]).print = 1;
1346: }
1347: }
1.15 takayama 1348:
1349: *tableOfxcolorForPS = table;
1350: return size;
1351: }
1352:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>