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