Annotation of OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c, Revision 1.25
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.25 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c,v 1.24 2004/03/01 05:48:24 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 ) {
1.25 ! noro 843: if ( can->color ) {
! 844: set_drawcolor(can->color);
! 845: XCopyArea(display,can->pix,can->window,
! 846: cdrawGC,0,0,can->width,can->height,0,0);
! 847: } else
! 848: XCopyArea(display,can->pix,can->window,
! 849: drawGC,0,0,can->width,can->height,0,0);
1.1 noro 850: pline(display,can,can->window);
851: XFlush(display);
852: }
853: }
854:
855: copy_subimage(subcan,can,pos)
856: struct canvas *subcan,*can;
857: XPoint pos;
858: {
859: if ( display ) {
860: XCopyArea(display,subcan->pix,can->pix,
861: drawGC,0,0,subcan->width,subcan->height,pos.x,pos.y);
862: XFlush(display);
863: }
864: }
865:
866: #include <signal.h>
867: #include <fcntl.h>
868:
869: set_selection() {
870: if ( current_can ) {
871: XSelectInput(display,current_can->window,0);
872: XFlush(display);
873: }
874: }
875:
876: reset_selection() {
877: if ( current_can ) {
878: XSelectInput(display,current_can->window,NormalSelection);
879: XFlush(display);
880: }
881: }
882:
883: set_busy(can)
884: struct canvas *can;
885: {
886: busy = 1;
887: XtSetSensitive(can->wideb,False);
888: XtSetSensitive(can->preciseb,False);
889: XtSetSensitive(can->noaxisb,False);
890: XFlush(display);
891: }
892:
893: reset_busy(can)
894: struct canvas *can;
895: {
896: busy = 0;
897: if ( can->window ) {
898: XtSetSensitive(can->wideb,True);
899: XtSetSensitive(can->noaxisb,True);
900: if ( can->mode == MODE_IFPLOT && qpcheck((Obj)can->formula) )
901: XtSetSensitive(can->preciseb,True);
902: XFlush(display);
903: }
904: }
905:
906: reset_current_computation()
907: {
908: if ( current_can ) {
909: reset_selection(); reset_busy(current_can);
910: define_cursor(current_can->window,normalcur);
911: }
1.8 takayama 912: }
913:
914: static struct canvas *Can;
915: /* void print_canvas(Widget w,struct canvas *can, XtPointer calldata); */
916: static void output_to_file(Widget , XtPointer, XtPointer );
917: static void output_to_ps_printer(Widget , XtPointer, XtPointer );
918: static void cancel_output_to_file(Widget , XtPointer,XtPointer);
919: static void generate_psfile(struct canvas *can, FILE *fp);
920: static void set_printing_method(Widget,XtPointer,XtPointer);
921: static void method_is_not_available();
922: static Widget PrintDialog;
923: static Widget PrintDialog_lp;
924: static Widget W;
925: static char *Fname = NULL;
926: static char *PrinterName = NULL;
927: #define PRINTING_METHOD_BITMAP 0
928: #define PRINTING_METHOD_VECTOR 1
929: static int PrintingMethod = PRINTING_METHOD_BITMAP;
930: static String Printing_methods[]={
931: "bitMap","vector",
932: };
933: static int N_printing_methods = 2;
934:
935: /*
936: static Widget create_printing_method_bar(Widget parent) {
937: Widget panel, button;
938: int i,n;
939: Arg wargs[1];
940: panel = XtCreateManagedWidget("printing methods",panedWidgetClass,
941: parent,NULL,0);
942: for (i=0; i<N_printing_methods; i++) {
943: button = XtCreateManagedWidget(Printing_methods[i],menuButtonWidgetClass,
944: panel,NULL,0);
945: fprintf(stderr,"button=%x\n",(int) button);
946: XtAddCallback(button,XtNcallback,set_printing_method,(XtPointer) i);
947: }
948: return(panel);
949: }
950: */
951:
952:
953: static void print_canvas(w,can,calldata)
954: Widget w;
955: struct canvas *can;
956: XtPointer calldata;
957: {
958: Widget fshell,fdialog;
959: extern struct canvas *Can;
960: extern Widget W;
961: Widget entry;
962: int i;
963: Arg arg[1];
964: static void output_to_printer();
965: static void print_canvas_to_file();
966: static void printing_method();
967:
968: W = w;
969: Can = can;
970: create_popup(can->shell,"Print/Output PS file","",&fshell,&fdialog);
971: XawDialogAddButton(fdialog,"print",output_to_printer,w);
972: XawDialogAddButton(fdialog,"output PS file",print_canvas_to_file,w);
973: XawDialogAddButton(fdialog,"method",printing_method,w);
974: XawDialogAddButton(fdialog,"dismiss",cancel_output_to_file,w);
975: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24 noro 976: SetWM_Proto(fshell);
1.8 takayama 977: }
978:
979: static void set_printing_method(Widget w,XtPointer number,XtPointer call_data) {
980: Widget shell;
981: extern int PrintingMethod;
982: PrintingMethod = (int) number;
983: fprintf(stderr,"PrintingMethod=%d\n",number);
984: shell = XtParent(XtParent(w));
985: XtPopdown(shell); XtDestroyWidget(shell);
986: }
987:
988: static void printing_method(w,can,calldata)
989: Widget w;
990: struct canvas *can;
991: XtPointer calldata;
992: {
993: Arg arg[10];
994: int i,n;
995: Widget fshell,fdialog;
996: extern struct canvas *Can;
997: extern int PrintingMethod;
998:
999: w = W;
1000: can = Can;
1001: create_popup(can->shell,"Printing method",Printing_methods[PrintingMethod],
1002: &fshell,&fdialog);
1003: n = 0;
1004: XtSetArg(arg[n], XtNlabel, "Method: "); n++;
1005: XtSetArg(arg[n], XtNvalue, Printing_methods[PrintingMethod]); n++;
1006: XtSetValues(fdialog,arg,n);
1007: for (i=0; i<N_printing_methods; i++) {
1008: XawDialogAddButton(fdialog,Printing_methods[i],set_printing_method,(XtPointer) i);
1009: }
1010: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24 noro 1011: SetWM_Proto(fshell);
1.8 takayama 1012: }
1013: static void print_canvas_to_file(w,can,calldata)
1014: Widget w;
1015: struct canvas *can;
1016: XtPointer calldata;
1017: {
1018: FILE *fp;
1019: Arg arg[10];
1020: int n;
1021: static char *psfile = NULL;
1022: Widget fshell,fdialog;
1023: extern struct canvas *Can;
1024: extern Widget PrintDialog;
1025: extern char *Fname;
1026:
1027: w = W;
1028: can = Can;
1029: if (psfile == NULL || Fname == NULL) psfile = "ox_plot.eps";
1030: else psfile = Fname;
1031: create_popup(can->shell,"Output as PS file",psfile,&fshell,&fdialog);
1032: n = 0;
1033: XtSetArg(arg[n], XtNlabel, "File : "); n++;
1034: XtSetArg(arg[n], XtNvalue, psfile); n++;
1035: XtSetValues(fdialog,arg,n);
1036: XawDialogAddButton(fdialog,"output to file",output_to_file,w);
1037: XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
1038: PrintDialog = fdialog;
1039: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24 noro 1040: SetWM_Proto(fshell);
1.8 takayama 1041: }
1042: static void output_to_printer(w,can,calldata)
1043: Widget w;
1044: struct canvas *can;
1045: XtPointer calldata;
1046: {
1047: FILE *fp;
1048: Arg arg[10];
1049: int n;
1050: static char *psfile = NULL;
1051: Widget fshell,fdialog;
1052: extern struct canvas *Can;
1053: extern Widget PrintDialog_lp;
1054: extern char *PrinterName;
1055:
1056: w = W;
1057: can = Can;
1058: if (psfile == NULL || PrinterName == NULL) psfile = "lp";
1059: else psfile = PrinterName;
1060: create_popup(can->shell,"Output PS file to printer",psfile,&fshell,&fdialog);
1061: n = 0;
1062: XtSetArg(arg[n], XtNlabel, "PS Printer Name : "); n++;
1063: XtSetArg(arg[n], XtNvalue, psfile); n++;
1064: XtSetValues(fdialog,arg,n);
1065: XawDialogAddButton(fdialog,"output to PS printer",output_to_ps_printer,w);
1066: XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
1067: PrintDialog_lp = fdialog;
1068: XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24 noro 1069: SetWM_Proto(fshell);
1.8 takayama 1070: }
1071:
1072: static void cancel_output_to_file(w,fbutton,call)
1073: Widget w;
1074: XtPointer fbutton, call;
1075: {
1076: Widget shell = XtParent(XtParent(w));
1077: XtPopdown(shell); XtDestroyWidget(shell);
1078: XtSetSensitive(fbutton,True);
1079: }
1080:
1081: static void output_to_file(w,fbutton,call)
1082: Widget w;
1083: XtPointer fbutton, call;
1084: {
1085: char *fname;
1086: FILE *fp;
1087: int i;
1088: char *m;
1089: extern struct canvas *Can;
1090: extern Widget PrintDialog;
1091: extern int PrintingMethod;
1092: Widget shell = XtParent(XtParent(w));
1093:
1094: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1095: }else{
1096: method_is_not_available();
1097: XtPopdown(shell); XtDestroyWidget(shell);
1098: XtSetSensitive(fbutton,True);
1099: return;
1100: }
1101:
1102: fname = XawDialogGetValueString(PrintDialog);
1103: Fname = (char *)malloc(sizeof(char)*strlen(fname)+1);
1104: strcpy(Fname,fname);
1105: for (i=0; i<strlen(Fname); i++) {
1106: if (Fname[i] == 0xd || Fname[i] == 0xa) {
1107: Fname[i] = 0; break;
1108: }
1109: }
1110: fprintf(stderr,"fname=%s\n",Fname); fflush(NULL);
1111: fp = fopen(Fname,"w");
1112: if (fp == NULL) {
1113: warning(Can,"Could not open the output file.");
1114: }else{
1115: generate_psfile(Can,fp);
1116: fclose(fp);
1117: }
1118:
1119: XtPopdown(shell); XtDestroyWidget(shell);
1120: XtSetSensitive(fbutton,True);
1121: }
1122:
1123: static void output_to_ps_printer(w,fbutton,call)
1124: Widget w;
1125: XtPointer fbutton, call;
1126: {
1127: char *printerName;
1128: FILE *fp;
1129: extern struct canvas *Can;
1130: extern Widget PrintDialog_lp;
1131: char fname[256];
1132: char cmd[512];
1133: static int id = 0;
1134: int i;
1135: Widget shell = XtParent(XtParent(w));
1136:
1137: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1138: }else{
1139: method_is_not_available();
1140: XtPopdown(shell); XtDestroyWidget(shell);
1141: XtSetSensitive(fbutton,True);
1142: return;
1143: }
1144:
1145: sprintf(fname,"/tmp/ox_plot_%d.eps",(int) getpid(),id++);
1146:
1147: printerName = XawDialogGetValueString(PrintDialog_lp);
1148: PrinterName = (char *)malloc(sizeof(char)*strlen(printerName)+1);
1149: strcpy(PrinterName,printerName);
1150: for (i=0; i<strlen(PrinterName); i++) {
1151: if (PrinterName[i] == 0xd || PrinterName[i] == 0xa) {
1152: PrinterName[i] = 0; break;
1153: }
1154: }
1155: fprintf(stderr,"printerName=%s\n",PrinterName); fflush(NULL);
1156: fp = fopen(fname,"w");
1157: if (fp == NULL) {
1158: warning(Can,"Could not open the output file.");
1159: }else{
1160: generate_psfile(Can,fp);
1161: fclose(fp);
1162: }
1163:
1164: sprintf(cmd,"lpr -P%s %s",PrinterName,fname);
1165: if (system(cmd)) {
1166: warning(Can,"Unknown printer?");
1167: }
1168: sprintf(cmd,"rm -f %s",fname);
1169: system(cmd);
1170: XtPopdown(shell); XtDestroyWidget(shell);
1171: XtSetSensitive(fbutton,True);
1172: }
1173:
1174:
1175: /* test sequence
1176: ox_launch(0,"ox_plot");
1177: ifplot(x^2-y^3);
1178: drawcircle(0,0,100,0,0);
1179: */
1.15 takayama 1180: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
1181: struct xcolorForPS **tableOfxcolorForPS);
1182:
1.8 takayama 1183: static void generate_psfile(can,fp)
1184: struct canvas *can;
1185: FILE *fp;
1186: {
1187: int x,y;
1188: XImage *image;
1189: int color[1];
1190: int colorSize = 1;
1191: char *m;
1.15 takayama 1192: struct xcolorForPS *tableOfxcolorForPS;
1.8 takayama 1193: extern int PrintingMethod;
1194: fprintf(stderr,"generate_psfile\n");
1195: if (PrintingMethod == PRINTING_METHOD_BITMAP) {
1196: if ( display ) {
1197: fprintf(stderr,"generate_psfile: output to a file.\n");
1198: image = XGetImage(display,can->pix,
1199: 0,0,can->width,can->height,-1,ZPixmap);
1.15 takayama 1200: colorSize =
1201: getColorSizeOfImageForPS(can->width,can->height,image,&tableOfxcolorForPS);
1202: color[0] = 0; /* black line */
1.18 noro 1203: generatePS_from_image(fp,image,can->width,can->height,color,colorSize,can,tableOfxcolorForPS,upsidedown);
1.8 takayama 1204: }else{
1205: fprintf(stderr,"Cannot print on this system\n");
1206: }
1207: }else{
1208: method_is_not_available();
1209: }
1210: fflush(NULL);
1211: }
1212:
1213: static void method_is_not_available() {
1214: char *m;
1215: #define MSG1 "Printing method \""
1216: #define MSG2 "\" is not available for this picture."
1217: m = (char *)malloc(strlen(MSG1)+strlen(MSG2)+strlen(Printing_methods[PrintingMethod])+1);
1218: strcpy(m,MSG1);
1219: strcat(m,Printing_methods[PrintingMethod]);
1220: strcat(m,MSG2);
1221: warning(Can,m);
1.9 noro 1222: }
1223:
1224: clear_pixmap(can)
1225: struct canvas *can;
1226: {
1227: XFillRectangle(display,can->pix,clearGC,0,0,can->width,can->height);
1228: XFlush(display);
1.1 noro 1229: }
1.15 takayama 1230:
1231: /*
1232: The following functions are used to generate color postscript file.
1233: */
1234: /* In order to count colorSize, binary tree (sm_btree) is used. */
1235: static struct sm_btree *sm_newNode(unsigned long v);
1236: static int sm_insert(struct sm_btree *node,unsigned long v);
1237: static int sm_count(struct sm_btree *rootp);
1.17 takayama 1238:
1.15 takayama 1239: struct sm_btree {
1240: unsigned long p;
1241: struct sm_btree * left;
1242: struct sm_btree * right;
1243: };
1244: static struct sm_btree *sm_newNode(unsigned long v) {
1245: struct sm_btree * n;
1246: n = (struct sm_btree *)MALLOC(sizeof(struct sm_btree));
1247: if (n == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
1248: n->p = v;
1249: n->left = NULL;
1250: n->right = NULL;
1251: return n;
1252: }
1253: static int sm_insert(struct sm_btree *node,unsigned long v)
1254: {
1255: if (node->p == v) return;
1256: if (node->p > v) {
1257: if (node->left == NULL) {
1258: node->left = sm_newNode(v);
1259: return;
1260: }
1261: sm_insert(node->left,v);
1262: }
1263: if (node->p < v) {
1264: if (node->right == NULL) {
1265: node->right = sm_newNode(v);
1266: return;
1267: }
1268: sm_insert(node->right,v);
1269: }
1270: }
1271: static int sm_count(struct sm_btree *rootp)
1272: {
1273: if (rootp == NULL) return 0;
1274: return (1+sm_count(rootp->left)+sm_count(rootp->right));
1275: }
1276:
1.16 takayama 1277: static int setTableOfxcolorForPS(struct sm_btree *rootp,
1278: struct xcolorForPS *table,int k,int size)
1279: {
1280: int m;
1281: m = k;
1282: if (rootp == NULL) return;
1283: if (k >= size) {
1284: warning(Can,"internal error of setTableOfxcolorForPS");
1285: }
1286: if (rootp->left != NULL) {
1287: m = setTableOfxcolorForPS(rootp->left,table,k,size);
1288: }
1289:
1290: (table[m]).pixel = rootp->p;
1291: m++;
1292: if (rootp->right != NULL) {
1293: m = setTableOfxcolorForPS(rootp->right,table,m,size);
1294: }
1295: return m;
1296: }
1297:
1298:
1.15 takayama 1299: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
1300: struct xcolorForPS **tableOfxcolorForPS)
1301: {
1302: int x,y;
1303: int size;
1304: struct sm_btree root;
1305: struct xcolorForPS *table;
1.16 takayama 1306: XStandardColormap scm;
1307: Colormap cm;
1308: XColor color;
1309: XColor white;
1310: int screen,i;
1311:
1.15 takayama 1312: root.p = 0;
1313: root.left = NULL; root.right=NULL;
1314: /* get color size */
1315: for (x=0; x<xsize; x++) {
1316: for (y=0; y<ysize; y++) {
1317: sm_insert(&root,XGetPixel(image,x,y));
1318: }
1319: }
1320: size=sm_count(&root);
1321:
1322: table = (struct xcolorForPS *)MALLOC((size+1)*sizeof(struct xcolorForPS));
1323: if (table == NULL) {
1324: fprintf(stderr,"No more memory in getColorSizeOfImageForPS.\n");
1325: return 0;
1326: }
1327: /* Set rgb values standing for the pixel values.
1328: */
1.16 takayama 1329: if (setTableOfxcolorForPS(&root,table,0,size) != size) {
1330: warning(Can,"internal error.");
1331: return ;
1332: }
1333:
1334: screen = DefaultScreen(display);
1335: cm = DefaultColormap(display,screen);
1336: /* BUG: it does not work.
1337: if (!XGetStandardColormap(display,RootWindow(display,DefaultScreen(display)),&scm,XA_RGB_DEFAULT_MAP)) {
1338: warning(Can,"failed to open the X Standard Colormap.");
1339: scm.red_max = 0xffff;
1340: scm.green_max = 0xffff;
1341: scm.blue_max = 0xffff;
1342: }
1343: */
1344: /* Set by hand. */
1345: scm.red_max = 0xffff;
1346: scm.green_max = 0xffff;
1347: scm.blue_max = 0xffff;
1348: XParseColor(display,cm,"White",&white);
1349: for (i=0; i<size; i++) {
1350: color.pixel=(table[i]).pixel;
1351: /*
1352: {
1353: char s[254];
1354: sprintf(s,"%ld",color.pixel);
1355: warning(Can,s);
1356: }
1357: */
1358: XQueryColor(display,cm,&color);
1359: (table[i]).r = ((double) color.red)/((double) scm.red_max);
1360: (table[i]).g = ((double) color.green)/((double) scm.green_max);
1361: (table[i]).b = ((double) color.blue)/((double) scm.blue_max);
1362: if ((table[i]).r > 1.0) (table[i]).r = 1.0;
1363: if ((table[i]).g > 1.0) (table[i]).g = 1.0;
1364: if ((table[i]).b > 1.0) (table[i]).b = 1.0;
1365: if (color.red == white.red && color.green == white.green
1366: && color.blue == white.blue) {
1367: (table[i]).print = 0;
1368: }else{
1369: (table[i]).print = 1;
1370: }
1371: }
1.15 takayama 1372:
1373: *tableOfxcolorForPS = table;
1374: return size;
1375: }
1376:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>