1 /*
2    Widgetklasse:	XwHistspectrWidgetClass
3    WHistspectr.c
4 
5 $Revision: 2.1 $
6 
7 $Log: Whistspectr.c,v $
8 Revision 2.1  2003/12/27 13:41:22  keidel
9 Whistspectr added
10 
11 
12 
13 
14         This program is free software; you can redistribute it and/or modify
15         it under the terms of the GNU General Public License as published by
16         the Free Software Foundation; either version 2, or (at your option)
17         any later version.
18 
19         This program is distributed in the hope that it will be useful,
20         but WITHOUT ANY WARRANTY; without even the implied warranty of
21         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22         GNU General Public License for more details.
23 
24         You should have received a copy of the GNU General Public License
25         along with this program; if not, write to the Free Software
26         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28 
29 /******************************************************************
30    Widgetclass:		XwHistspectrWidgetClass
31 
32    written by: 	WizAnt Software
33    		J�rgen Keidel
34    		Bergstrasse 15
35    		D 85080 Gaimersheim
36    		Tel: D  08406 379
37    		E-mail: wizant.keidel@freenet.de
38    		2003
39 
40 ******************************************************************/
41 /*	History:    initial: Tue Dec  9 08:14:39 CET 2003
42 
43 
44 
45 */
46 /* include */
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #ifdef LINUX
51 #define __USE_BSD
52 #endif
53 #include <math.h>
54 #include  <limits.h>
55 #include <X11/Xlib.h>
56 #include<Xm/PrimitiveP.h>
57 #include<Xm/DrawP.h>
58 
59 
60 #include <Whistspectr.h>
61 
62 
63 #ifdef __cplusplus
64 extern "C"{
65 #endif
66 
67 #define offset(field) XtOffsetOf(XwHistspectrRec, field)
68 #ifndef strdup
69 char *strdup(const char *s);
70 #endif
71 
72 
73 
74 /****** private Funktions Deklaration ******/
75 #ifdef _NO_PROTO
76 
77 /* Deklaration der Methoden */
78 static void     Initialize();
79 static Boolean  SetValues ();
80 static void     Redisplay();
81 static void     Resize();
82 static void     Destroy(  );
83 
84 /* Deklaration der privaten Funktionen */
85 static void     get_proportion();
86 static void     Gethistspectr_gc();
87 static void     clear_histspectr();
88 static void     scale();
89 static void     drawgrid();
90 static void     drawspectr();
91 static void     drawannot();
92 static void     copyannot();
93 static void     copypix();
94 static void     dancevals();
95 #else
96 
97 /* Deklaration der Methoden */
98 static void     Initialize       ( Widget , Widget , ArgList , Cardinal *);
99 static Boolean  SetValues        ( Widget curr, Widget requ, Widget new
100                                     , ArgList args , Cardinal *numargs);
101 static void     Redisplay        (Widget w, XEvent *event, Region region);
102 static void     Resize		 ( Widget );
103 static void     Destroy		 ( Widget );
104 
105 /* Deklaration der privaten Funktionen */
106 static void     get_proportion	 ( XwHistspectrWidget );
107 static void     Gethistspectr_gc ( XwHistspectrWidget  );
108 static void     clear_histspectr (XwHistspectrWidget );
109 static void     scale            (XwHistspectrWidget);
110 static void     drawgrid         (XwHistspectrWidget );
111 static void     drawspectr       (XwHistspectrWidget , w3dPoint *val
112                                     , float time , int npoints);
113 static void     drawannot        (XwHistspectrWidget  cw);
114 static void     copyannot        (XwHistspectrWidget  cw ,Drawable target
115                                     , double yoffset);
116 static void     copypix          (XwHistspectrWidget  cw );
117 static void     dancevals        (XwHistspectrWidget  cw );
118 #endif /* _NO_PROTO */
119 
120 
121 /* Definition der Resourcen-Liste */
122 
123 
124 static XtResource resources[] = {
125 /*
126  *     {
127  *     	XmNinputCallback,
128  *     	NULL,
129  *     	XtRCallback,
130  *     	sizeof(XtPointer),
131  *     	offset(histspectr.input_callback),
132  *     	XtRCallback,
133  *     	NULL
134  *
135  *   },
136  */
137   {
138     	XmNexposeCallback,
139     	XmCExposeCallback,
140     	XtRCallback,
141     	sizeof(XtPointer),
142     	offset(histspectr.expose_callback),
143     	XtRCallback,
144     	NULL
145 
146   },
147  {
148     	XmNresizeCallback,
149     	XmCResizeCallback,
150     	XtRCallback,
151     	sizeof(XtPointer),
152     	offset(histspectr.resize_callback),
153     	XtRCallback,
154     	NULL
155 
156   },
157  {
158    	XwNhistspectrAutoscale ,
159    	XwCHistspectrAutoscale,
160   	XtRInt ,
161   	sizeof(short int),
162   	offset(histspectr.autoscale),
163   	XtRImmediate,
164   	NoAuto
165   },
166  {
167    	XwNhistspectrGridScale ,
168    	XwCHistspectrGridScale,
169   	XtRFloat ,
170   	sizeof(float *),
171   	offset(histspectr.gr),
172   	XtRImmediate,
173   	NULL
174   },
175   {
176    	XwNhistspectrScale,
177    	XwCHistspectrScale,
178   	XtRFloat ,
179   	sizeof(float *),
180   	offset(histspectr.vis),
181   	XtRImmediate,
182   	NULL
183   },
184  {
185    	XwNhistspectrAnnotColor,       /* annotation foreground */
186    	XwCHistspectrAnnotColor,
187   	XtRPixel ,
188   	sizeof(Pixel),
189   	offset(histspectr.anncolor),
190   	XtRImmediate,
191   	(XtPointer) 1
192   },
193 {
194    	XwNhistspectrBackground ,     /* background of curve window */
195    	XwCHistspectrBackground ,
196   	XtRPixel ,
197   	sizeof(Pixel),
198   	offset(histspectr.background),
199   	XtRImmediate,
200   	(XtPointer) 1
201   },
202    {
203    	XwNhistspectrAnnotTNdec,
204    	XwCHistspectrAnnotTNdec,
205   	XtRInt ,
206   	sizeof(int),
207   	offset(histspectr.tndecimals),
208   	XtRImmediate,
209   	(XtPointer) 0
210   },
211    {
212    	XwNhistspectrAnnotYNdec,
213    	XwCHistspectrAnnotYNdec,
214   	XtRInt ,
215   	sizeof(int),
216   	offset(histspectr.yndecimals),
217   	XtRImmediate,
218   	(XtPointer) 0
219   },
220     {
221    	XwNhistspectrAnnotXNdec,
222    	XwCHistspectrAnnotXNdec,
223   	XtRInt ,
224   	sizeof(int),
225   	offset(histspectr.xndecimals),
226   	XtRImmediate,
227   	(XtPointer) 0
228   },
229  {
230    	XwNhistspectrAnnotXNgrid,
231    	XwCHistspectrAnnotXNgrid,
232   	XtRInt ,
233   	sizeof(int),
234   	offset(histspectr.xnthgridanno),
235   	XtRImmediate,
236   	(XtPointer) 0
237   },
238  {
239    	XwNhistspectrAnnotTNgrid,
240    	XwCHistspectrAnnotTNgrid,
241   	XtRInt ,
242   	sizeof(int),
243   	offset(histspectr.tnthgridanno),
244   	XtRImmediate,
245   	(XtPointer) 0
246   },
247    {
248    	XwNhistspectrAnnotYNgrid,
249    	XwCHistspectrAnnotYNgrid,
250   	XtRInt ,
251   	sizeof(int),
252   	offset(histspectr.ynthgridanno),
253   	XtRImmediate,
254   	(XtPointer) 0
255   },
256   {
257    	XwNhistspectrAnnotation,
258    	XwCHistspectrAnnotation,
259   	XtRBool ,
260   	sizeof(short int),
261   	offset(histspectr.anflag),
262   	XtRImmediate,
263   	(XtPointer) TRUE
264   },
265   {
266    	XwNhistspectrLines,
267    	XwCHistspectrLines,
268   	XtRBool ,
269   	sizeof(short int),
270   	offset(histspectr.lines),
271   	XtRImmediate,
272   	(XtPointer) TRUE
273   },
274  {
275    	XwNhistspectrAddtext,
276    	XwCHistspectrAddtext,
277   	XtRString,
278   	sizeof(char *),
279   	offset(histspectr.fixtext),
280   	XtRImmediate,
281   	(XtPointer) NULL
282   },
283  {
284    	XwNhistspectrFill,          /* fill area under curve */
285    	XwCHistspectrFill,
286   	XtRPixel ,
287   	sizeof(Pixel),
288   	offset(histspectr.fillcolor),
289   	XtRImmediate,
290   	(XtPointer) 1
291   },
292  {
293    	XwNhistspectrCurveColor,   /*  curve color (line)*/
294    	XwCHistspectrCurveColor,
295   	XtRPixel ,
296   	sizeof(Pixel),
297   	offset(histspectr.linecolor),
298   	XtRImmediate,
299   	(XtPointer) 1
300   },
301  {
302    	XwNhistspectrAngle,
303    	XwCHistspectrAngle,
304   	XtRInt,
305   	sizeof(int),
306   	offset(histspectr.Angle),
307   	XtRImmediate,
308   	(XtPointer) XwHistspectrDefaultAngle
309   },
310 {
311  	XmNfontList,
312  	XmCFontList,
313  	XmRFontList,
314  	sizeof(XmFontList),
315  	offset(histspectr.font_list),
316  	XtRImmediate,
317  	NULL
318   },
319 };
320 /*Definition der Translation  Tabelle */
321 
322 
323 /* Definition der Aktionen f�r die Translation-Tabelle */
324 
325 
326 
327 /* Klasseninitialisierung f�r die XwHistspectrClass */
328 
329 XwHistspectrClassRec xwHistspectrClassRec = {
330   {
331      /* core_Class Felder */
332      /* Superklasse		*/ (WidgetClass) & xmPrimitiveClassRec,
333      /* Klassenname		*/ "XwHistspectr",
334      /* Widget groesse	    	*/ sizeof(XwHistspectrRec),
335      /* Class_initialize	*/ NULL,
336      /* Class_part_initialize	*/ NULL,
337      /* class_inited intern	*/ FALSE,
338      /* initialize		*/ Initialize,
339      /* initialize_hook (dynami)*/ NULL,
340      /* realize	(XCreateWindow)	*/ XtInheritRealize,
341      /* actions		    	*/ NULL,
342      /* Anzahl der Action	*/ 0,
343      /* Resourcen 		*/ resources,
344      /* Resourcen anzahl	*/ XtNumber(resources),
345      /* xrm_class intern	*/ NULLQUARK,
346      /* compressmotion 	    	*/ TRUE,
347      /* compress_exposure	*/ XtExposeCompressMaximal,
348      /* compress_enterleave	*/ TRUE,
349      /* VisibilityNotify	*/ FALSE,
350      /* destroy		    	*/ Destroy,
351      /* resize		    	*/ Resize,
352      /* expose		    	*/ Redisplay,
353      /* set_values		*/ SetValues,
354      /* set_values_hook	    	*/ NULL,
355      /* set_values_almost	*/ XtInheritSetValuesAlmost,
356      /* get_values_hook	    	*/ NULL,
357      /* accept_focus		*/ NULL,
358      /* version		    	*/ XtVersion,
359      /* callback_private	*/ NULL,
360      /* tm_table		*/NULL,
361      /* query_geometry	    	*/ NULL,
362      /* display_accelerator	*/ XtInheritDisplayAccelerator,
363      /* extension		*/ NULL
364   },
365   { /* Primitive_Class felder */
366     /* border_highlight	    	*/ NULL,
367     /* border_unhighlight	*/ NULL,
368     /* translations		*/ XtInheritTranslations,
369     /* arm_and_activate	    	*/ NULL,
370     /* syn resources		*/ NULL,
371     /* num_syn_resources	*/ 0,
372     /* extension	 	*/ NULL,
373   },
374   { /* Whistspectr_Class felder */
375     /* extensions 		*/ NULL,
376   },
377 };
378 
379 WidgetClass XwHistspectrWidgetClass = (WidgetClass) &xwHistspectrClassRec;
380 
381 
382 static   float  defaultscal[6]   = {0.0,100.0,0.0,100.0,0,100.0};
383 static   float  defaultgrid[6]   = {0.0,10.0,0.0,10.0,0.0,20.0};
384 
385 /***************************************************************************
386  ***************************************************************************
387  *
388  *  Functionname:	Initialize
389  *
390  *
391  *  Prototype:	static void Initialize (Widget treq, Widget tnew, ArgList args,
392  *			 Cardinal *num_args);
393  *
394  *  Input:		Widget treq, Widget tnew, ArgList args,
395  *			Cardinal *num_args
396  *
397  *  Output:
398  *
399  *  Return:
400  *
401  *  Documentation:	Method, called from X, creating the Widget.
402  *			The Instances are checked, dependent parameters
403  *			calculated from resources, pixmaps and GC's created
404  *			initial clearing of pixmaps, and setting the grid
405  *
406  *
407  *  History:		Sun Jan 18 08:57:43 CET 1998
408  *                      Tue Dec 16 13:27:10 CET 2003
409  *
410  ***************************************************************************
411  ***************************************************************************/
Initialize(Widget treq,Widget tnew,ArgList args,Cardinal * num_args)412  static void Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args)
413 {
414    XwHistspectrWidget new = (XwHistspectrWidget) tnew; /* Convert pointer type to Instancerecord */
415   float *interm;
416   Dimension width,height;
417 
418             /* for safety, cannot be smaller */
419        if(new->core.width < minsize)
420 		new->core.width = minsize;
421        if(new->core.height < minsize)
422 		new->core.height = minsize;
423        if(new->histspectr.fixtext && new->histspectr.fixtext[0] ){
424                 new->histspectr.fixtext = strdup(new->histspectr.fixtext);
425                 new->histspectr.dofixtext = TRUE;
426        }else{
427                 new->histspectr.fixtext = NULL;
428                 new->histspectr.dofixtext = FALSE;
429        }
430         new->histspectr.mark = 0;
431 	new->primitive.highlight_thickness = 0;
432 	/* copy scaling and grid definition over to internal storage, as application might free the array */
433 	interm = (float *)XtMalloc(sizeof(float)*6);
434 	if(!interm  )
435 		XtWarning("WHistspectr   create   cannot XtMalloc");
436 	if(new->histspectr.vis)
437 		memcpy(interm, new->histspectr.vis , 6*sizeof(float));
438 	else
439 		memcpy(interm,  defaultscal , 6*sizeof(float));
440 	new->histspectr.vis = interm;
441 	interm = (float *)XtMalloc(sizeof(float)*6);
442 	if(!interm  )
443 		XtWarning("WHistspectr   create   cannot XtMalloc");
444 	if(new->histspectr.gr	)
445 		memcpy(interm, new->histspectr.gr , 6*sizeof(float));
446 	else
447 		memcpy(interm, defaultgrid  , 6*sizeof(float));
448 	new->histspectr.angle = (M_PI * new->histspectr.Angle) / 180.0;
449 	new->histspectr.gr = interm;
450 	new->histspectr.sc.at = new->histspectr.gr[0];
451 	new->histspectr.exposed = 0;		/* count to get first exposure */
452 	new->histspectr.lastanncnt = 1;
453         new->histspectr.curve = NULL;
454         new->histspectr.curvepoint = 0;
455 
456   /* Wenn keine Fontliste durch Resourcen gesetzt ist,laden die Default-Fontliste */
457   	if (new->histspectr.font_list == NULL){
458     		new->histspectr.font_list =
459     		      _XmGetDefaultFontList((Widget) new, XmLABEL_FONTLIST);
460   	}
461 /* set all colours , is not explicitely set, inherit from parent */
462 	if (new->histspectr.background == 1)
463 	        new->histspectr.background = new->core.background_pixel;
464 	if(new->histspectr.anncolor == 1)
465 		new->histspectr.anncolor = new->primitive.foreground;
466 	if(new->histspectr.fillcolor == 1)
467             new->histspectr.fillcolor = new->histspectr.background;
468         if(new->histspectr.linecolor == 1)
469 	        new->histspectr.linecolor  = new->primitive.foreground;
470 
471 
472   /* Die Fonts f�r die Fontliste laden */
473   	if (new->histspectr.font_list ){
474    		 new->histspectr.font_list = XmFontListCopy(new->histspectr.font_list);
475     		_XmFontListGetDefaultFont( new->histspectr.font_list, &new->histspectr.font_struct);
476  	 }
477  	 else{
478     		new->histspectr.font_struct = XLoadQueryFont(XtDisplay(new), "fixed");
479  	 }
480  	 new->histspectr.panno = (Pixmap)NULL;
481 	 get_proportion(new);		/* calculate sizes and starting */
482 
483 	new->histspectr.pix = XCreatePixmap(XtDisplay(new),
484   		RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))),
485   		new->histspectr.pixwidth, new->histspectr.pixheight,
486   		new->core.depth);
487 
488   	if(new->histspectr.anflag ){
489 	      height = new->histspectr.pixheight;
490  	      width = new->histspectr.annsiz;
491   	      if(width > 0 && height > 0)
492 
493     	        new->histspectr.panno = XCreatePixmap(XtDisplay(new),
494   		  RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))),
495   		  width, height,new->core.depth);
496   	       else{
497   	       	new->histspectr.anflag  =  FALSE;
498   	       	XtWarning("Bad size, Annotation set to FALSE");
499   	       }
500 
501 	 }
502 
503     	new->histspectr.lasttim = new->histspectr.vis[0] ;
504 
505 	new->histspectr.foldx = new->histspectr.pixwidth - new->histspectr.width;
506 	new->histspectr.foldy = new->histspectr.height;
507 	new->histspectr.Xpos =  new->histspectr.width;
508 
509     	Gethistspectr_gc(new);
510 	scale(new);	/* scale the widget */
511 	drawgrid(new );
512         new->histspectr.lasttim = 0.0;
513 
514 }
515 
516 /***************************************************************************
517  ***************************************************************************
518  *
519  *  Functionname:		SetValues
520  *
521  *  Input:		Widget curr,Widget requ, Widget new, ArgList args, Cardinal *numargs
522  *
523  *  Return:
524  *
525  *  Documentation: Die Funktion wird von Xt als Methode aufgerufen wenn die Applikation
526  * 		  XtSetValue() oder XtSetValues() aufruft. In dieser Funktion wird �ber-
527  *		  pr�ft ob sich eine Wert der Ressourcen Variablen f�r die Widgetklasse
528  * 		  ge�ndert hat. Ist dies der Fall werden die davon abh�ngigen privaten
529  *		  Instanzvariablen neu berechnet.  Wenn sich die Skalierung, der Grid oder
530  *		  Annotation, bzw. Histspectr-Richtung geaendert hat, wird das Widget komplett
531  *		  neu gezeichnet.
532  *
533  *
534  *
535  *  History:	wizant   Sun Jan 18 08:58:14 CET 1998
536  *                       Tue Dec 16 13:27:10 CET 2003
537  *
538  ***************************************************************************
539  ***************************************************************************/
540 /* ARGSUSED */
541 
SetValues(Widget curr,Widget requ,Widget new,ArgList args,Cardinal * numargs)542 static Boolean SetValues ( Widget curr, Widget requ, Widget new, ArgList args, Cardinal *numargs){
543 
544   XwHistspectrWidget current = (XwHistspectrWidget) curr;
545   XwHistspectrWidget newon   = (XwHistspectrWidget) new;
546 
547   int i;
548   Boolean rescale = FALSE , reset = FALSE;
549   XGCValues values;
550   XtGCMask valuemask =  GCFont ;
551   float *interm , *oldinterm;
552   Dimension width,height;
553   unsigned long colorpix[4];
554 
555         if(!XwIsHistspectr(curr)){
556 		XtWarning("BAD widget id in XwHistspectr SetValues");
557 		return FALSE;
558 	}
559             /* for safety, cannot be smaller */
560        if(newon->core.width < minsize)
561 		newon->core.width = minsize;
562        if(newon->core.height < minsize)
563 		newon->core.height = minsize;
564 
565         i=0;
566         if(newon->histspectr.background != current->histspectr.background)
567                 colorpix[i++] = current->histspectr.background;
568         if(newon->histspectr.anncolor != current->histspectr.anncolor)
569                 colorpix[i++] = current->histspectr.anncolor;
570         if(newon->histspectr.fillcolor != current->histspectr.fillcolor)
571                 colorpix[i++] = current->histspectr.fillcolor;
572         if(newon->histspectr.linecolor != current->histspectr.linecolor)
573                 colorpix[i++] = current->histspectr.linecolor;
574         if(i)
575             XFreeColors(XtDisplay(current), DefaultColormap(XtDisplay(current)
576 		,DefaultScreen(XtDisplay(current))),colorpix,i,0);
577 
578 	if(newon->histspectr.xndecimals != current->histspectr.xndecimals){
579 		 get_proportion(newon);		/* recalculate sizes and starting */
580 		rescale = TRUE;
581 	}
582 
583 	if(newon->histspectr.yndecimals != current->histspectr.yndecimals){
584 		 get_proportion(newon);		/* recalculate sizes and starting */
585 		rescale = TRUE;
586 	}
587         if(newon->histspectr.fixtext != current->histspectr.fixtext){
588             if(current->histspectr.fixtext ){
589                 free(current->histspectr.fixtext);
590                 current->histspectr.fixtext = NULL;
591             }
592             if(newon->histspectr.fixtext && newon->histspectr.fixtext[0]){
593                 newon->histspectr.fixtext = strdup(newon->histspectr.fixtext);
594                 newon->histspectr.dofixtext = TRUE;
595             }else{
596                 newon->histspectr.fixtext = NULL;
597                 newon->histspectr.dofixtext = FALSE;
598             }
599         }
600         if(newon->histspectr.autoscale & AutoAbs)
601             newon->histspectr.lasttim = 0;
602   /* Pr�fen ob sich die Fontliste ge�ndert hat */
603   	if(newon->histspectr.font_list != current->histspectr.font_list){
604     		if((current->histspectr.font_list == NULL) &&
605     		     (current->histspectr.font_struct != NULL))
606       			XFreeFont(XtDisplay(current), current->histspectr.font_struct);
607 
608     		if( current->histspectr.font_list)
609       			XmFontListFree(current->histspectr.font_list);
610 
611     		if( newon->histspectr.font_list == NULL)
612      			newon->histspectr.font_list =
613            			      _XmGetDefaultFontList((Widget) newon, XmLABEL_FONTLIST);
614 
615    	 	if( newon->histspectr.font_list != NULL){
616      		       newon->histspectr.font_list = XmFontListCopy(newon->histspectr.font_list);
617      		      _XmFontListGetDefaultFont(newon->histspectr.font_list,
618        			&newon->histspectr.font_struct);
619     		}
620     		else
621       		     newon->histspectr.font_struct = XLoadQueryFont(XtDisplay(newon),"fixed");
622 /* now push font to GC's */
623   		values.font = newon->histspectr.font_struct->fid;
624 		 XChangeGC(XtDisplay(newon), newon->histspectr.gc, valuemask, &values);
625 		 XChangeGC(XtDisplay(newon), newon->histspectr.anngc, valuemask, &values);
626 
627    	}
628         if(newon->histspectr.Angle != current->histspectr.Angle){
629             newon->histspectr.angle = (M_PI * newon->histspectr.Angle) / 180.0;
630             rescale = TRUE;
631             reset = TRUE;
632         }
633 /* check and recalculate display relative parameters, recreate pixmaps */
634 	if( newon->histspectr.anflag   != current->histspectr.anflag
635 	   || newon->histspectr.dofixtext   != current->histspectr.dofixtext){
636 	      if(newon->histspectr.pix)
637 	  	  XFreePixmap(XtDisplay(newon),newon->histspectr.pix);
638 	      if(newon->histspectr.panno)
639 	  	  XFreePixmap(XtDisplay(newon),newon->histspectr.panno);
640 	      newon->histspectr.panno = (Pixmap)NULL;	/* put NULL in, there is no pixmap */
641 
642 
643 	      get_proportion(newon);		/* recalculate sizes and starting */
644 
645 
646 	      newon->histspectr.pix = XCreatePixmap(XtDisplay(newon),
647   	                RootWindow(XtDisplay(newon), DefaultScreen(XtDisplay(newon))),
648   	      newon->histspectr.pixwidth, newon->histspectr.pixheight,
649   	      newon->core.depth);
650   	      if(newon->histspectr.anflag ){
651    	            height = newon->histspectr.pixheight;
652  	      	    width = newon->histspectr.annsiz;
653  	            if(width > 0 && height > 0)
654     	                newon->histspectr.panno = XCreatePixmap(XtDisplay(newon),
655   		            RootWindow(XtDisplay(newon), DefaultScreen(XtDisplay(newon))),
656   		            width, height,newon->core.depth);
657  	     }
658 
659 
660 	    rescale = TRUE;
661 	}
662 
663 /* set all colors if changed or not into GC */
664 
665 	XSetForeground(XtDisplay(newon) , newon->histspectr.gc,newon->histspectr.linecolor);
666 	XSetForeground(XtDisplay(newon) , newon->histspectr.anngc,newon->histspectr.anncolor);
667 	XSetBackground(XtDisplay(newon) , newon->histspectr.gc,newon->histspectr.background);
668 	XSetBackground(XtDisplay(newon) , newon->histspectr.anngc,newon->core.background_pixel);
669 
670 	/* copy scaling and grid definition over to internal storage, as application might free the array */
671 	if(newon->histspectr.vis != current->histspectr.vis ){
672     	   reset = TRUE;
673 	    oldinterm = current->histspectr.vis;
674 	    interm = 	newon->histspectr.vis;
675 	    newon->histspectr.vis = (float *)XtMalloc(sizeof(float)*6);
676   	    if(!newon->histspectr.vis ) {
677                 XtWarning("WHistspectr   SetValues   cannot XtMalloc");
678                 newon->histspectr.vis = oldinterm;
679             }else{
680                 memcpy(newon->histspectr.vis , interm , 6*sizeof(float));
681                 if(current->histspectr.vis)
682                     XtFree((char *)current->histspectr.vis);
683 	    }
684 	    rescale = TRUE ;
685 	}
686 	if(newon->histspectr.gr != current->histspectr.gr ){
687             reset = TRUE;
688 	    interm = newon->histspectr.gr;
689 	    oldinterm = current->histspectr.gr;
690 	    newon->histspectr.gr = (float *)XtMalloc(sizeof(float)*6);
691   	    if(!newon->histspectr.gr ) {
692  		XtWarning("WHistspectr   SetValues   cannot XtMalloc");
693  		newon->histspectr.gr = oldinterm;
694  	    }else{
695 		memcpy(newon->histspectr.gr, interm , 6*sizeof(float));
696 		if(current->histspectr.gr)
697 		    XtFree((char *)current->histspectr.gr);
698 	    }
699 	    rescale = TRUE ;
700 	    newon->histspectr.sc.at = newon->histspectr.gr[0];
701 	}
702 
703    	if(newon->histspectr.tndecimals != current->histspectr.tndecimals)
704    		current->histspectr.tndecimals =newon->histspectr.tndecimals;
705    	if(newon->histspectr.xndecimals != current->histspectr.xndecimals)
706    		current->histspectr.xndecimals = newon->histspectr.xndecimals , rescale=TRUE;
707 
708 	/** now redisplay etc */
709 	if(rescale){
710 /* rescale all and clear pixmap, create grid and copy it into visible */
711             newon->histspectr.mark = 0;
712 	    scale (newon);		/* new scaling */
713 	    clear_histspectr(newon);
714 	/******************* re-offset */
715 
716 		/* for(i=0;i<newon->histspectr.nactc;i++){ */		/* first rescale all oldpoints in bars */
717     	    if(reset){
718     	        newon->histspectr.Xoffset = newon->histspectr.pixwidth - newon->histspectr.width;
719 	        newon->histspectr.Yoffset = 0;
720 			/* newon->histspectr.init = 0; */
721 	        newon->histspectr.oldx =  newon->histspectr.pixwidth - newon->histspectr.width;
722 	        newon->histspectr.oldy = newon->histspectr.foldy = 0;
723 	        newon->histspectr.foldx = newon->histspectr.oldx ;
724 	    }else {
725     	        newon->histspectr.foldx = (newon->histspectr.pixwidth - newon->histspectr.width) -
726 		        (newon->histspectr.lasttim- newon->histspectr.sc.at ) *
727 	 		newon->histspectr.sc.bt * cos(newon->histspectr.angle);
728 	        newon->histspectr.oldx = 	newon->histspectr.foldx;
729  	        newon->histspectr.foldy = (newon->histspectr.lasttim - newon->histspectr.sc.at ) *
730 	 	        newon->histspectr.sc.bt * sin(newon->histspectr.angle);
731 	        newon->histspectr.oldy = newon->histspectr.foldy;
732 	    }
733 		/* } */
734 
735 	/* need a clear */
736 	    drawgrid(newon);
737 	    if(newon->histspectr.exposed){
738  	     	XClearArea(XtDisplay(newon), XtWindow(newon), newon->histspectr.xv, 0,
739  	     	    newon->histspectr.width, XtHeight(newon), FALSE);
740 		drawannot(newon);
741 	    }
742 	}
743 	return TRUE;
744 }
745 
746 
747 
748 
749 /***************************************************************************
750  ***************************************************************************
751  *
752  *  Functionname:	get_proportion
753  *
754  *
755  *  Prototype:	static void get_proportion(XwHistspectrWidget cw);
756  *
757  *  Input:		XwHistspectrWidget cw
758  *
759  *  Output:
760  *
761  *  Return:
762  *
763  *  Documentation:	calculates all sizedependent parameters inside the
764  *			widget. Visible part size and position, pixmap sizes
765  *
766  *
767  *  History:	Sun Jan 18 08:58:33 CET 1998
768  *              Tue Dec 16 13:27:10 CET 2003
769  *
770  ***************************************************************************
771  ***************************************************************************/
get_proportion(XwHistspectrWidget cw)772 static void get_proportion(XwHistspectrWidget cw){
773 
774   int  len  , cheight =  (cw->histspectr.font_struct->ascent - cw->histspectr.font_struct->descent);
775   char  annot[40];
776 
777 
778    	cw->histspectr.width = XtWidth(cw)  ;
779 	cw->histspectr.height = XtHeight(cw) ;
780 
781 	cw->histspectr.xv = cw->histspectr.yv = 0;
782 		/* correct illegal annotation-flag combinations */
783         if(cw->histspectr.anflag){
784 	    cw->histspectr.yv += (cheight+2)*2;
785 	    if(cw->histspectr.dofixtext)
786 	        cw->histspectr.yv += cheight+2;
787 	    cw->histspectr.height -= cw->histspectr.yv  ;
788 
789 	    sprintf(annot,"% .*f", cw->histspectr.yndecimals,(cw->histspectr.vis[2]
790 		          +cw->histspectr.vis[3])*10.);
791 	    len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) +8; /* grid space 6 pixels */
792 	    cw->histspectr.width -= len;
793 	    cw->histspectr.xv = len ;
794             sprintf(annot,"% .*f", cw->histspectr.tndecimals,cw->histspectr.vis[1]*100.);
795 	    len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) +8;
796 	    cw->histspectr.width -= len;
797 	    cw->histspectr.annsiz =  len;         /* width of annotation pixmap */
798 	}
799         if((signed short)cw->histspectr.width < 0)
800             cw->histspectr.width = XtWidth(cw)  ;
801         if((signed short )cw->histspectr.height  < 0)
802             cw->histspectr.height = XtHeight(cw) ;
803 	cw->histspectr.pixwidth  = cw->histspectr.width * 3;   /* 3 times bigger pixmap */
804 	cw->histspectr.pixheight  = cw->histspectr.height * 3;
805     	cw->histspectr.Xoffset = cw->histspectr.pixwidth - cw->histspectr.width;
806 	cw->histspectr.Yoffset = 0;
807 
808 }
809 
810 /***************************************************************************
811  ***************************************************************************
812  *
813  *  Functionname:	Gethistspectr_gc
814  *
815  *
816  *  Prototype:	static void Gethistspectr_gc(XwHistspectrWidget  cw);
817  *
818  *  Input:		XwHistspectrWidget  cw
819  *
820  *  Output:
821  *
822  *  Return:
823  *
824  *  Documentation:	Creates all needed GC's setting the font to all of them
825  *			setting background/foreground colours from resources
826  *
827  *
828  *  History:		Sun Jan 18 08:58:51 CET 1998
829  *                      Tue Dec 16 13:27:10 CET 2003
830  *
831  ***************************************************************************
832  ***************************************************************************/
Gethistspectr_gc(XwHistspectrWidget cw)833 static void Gethistspectr_gc(XwHistspectrWidget  cw){
834 
835   XGCValues values;
836   XtGCMask mask = GCForeground | GCBackground | GCFont ;
837 
838   /* Erzeugendes diagram GCs  */
839   	values.foreground = cw->primitive.foreground;
840   	values.background = cw->histspectr.background;
841   	values.font = cw->histspectr.font_struct->fid;
842   	cw->histspectr.gc = XCreateGC(XtDisplay(cw),cw->histspectr.pix, mask, &values);
843   /* Erzeugen des annotation GCs  */
844   	values.foreground = cw->histspectr.anncolor;
845     	values.background = cw->core.background_pixel;
846   	cw->histspectr.anngc = XCreateGC(XtDisplay(cw),cw->histspectr.pix, mask, &values);
847 
848 /*   Create the GC for dancevals etc */
849    	values.foreground = cw->primitive.foreground;
850   	values.background = cw->histspectr.background;
851   	values.font = cw->histspectr.font_struct->fid;
852 
853 	clear_histspectr(cw );
854 
855 
856 
857 }
858 
859 
860 /***************************************************************************
861  ***************************************************************************
862  *
863  *  Functionname:	Redisplay
864  *
865  *
866  *  Prototype:	static void Redisplay(Widget w, XEvent *event, Region region);
867  *
868  *  Input:		Widget w, XEvent *event, Region region
869  *
870  *  Output:
871  *
872  *  Return:
873  *
874  *  Documentation:	This is the Expose method for X
875  *		The region and event parameter are ignored.
876  *		actually the active pixmap parts are replotted and the
877  *		annotation redrawed
878  *
879  *
880  *  History:	Sun Jan 18 08:59:13 CET 1998
881  *              Tue Dec 16 13:27:10 CET 2003
882  *
883  ***************************************************************************
884  ***************************************************************************/
885 
Redisplay(Widget w,XEvent * event,Region region)886 static void Redisplay(Widget w, XEvent *event, Region region){
887 
888   XwHistspectrWidget cw = (XwHistspectrWidget) w;
889   XwHistspectrCallbackStruct call_value;
890   XExposeEvent *xexpose =(XExposeEvent *)event;
891 
892   /* Pr�fen ob die Widgetinstanz schon realisiert ist */
893  	 if ( !XtIsRealized((Widget)cw) )
894 		return;
895     if(xexpose->count)
896         return;
897   /* Fenster aktualisieren */
898     if(cw->histspectr.exposed)
899         copypix(cw );
900     drawannot(cw);
901     cw->histspectr.exposed++;
902     if(cw->histspectr.expose_callback){
903         call_value.reason = XmCR_EXPOSE;
904         call_value.event = event;
905         call_value.fd = -1;
906         call_value.width = cw->histspectr.width;
907         call_value.height = cw->histspectr.height;
908                 /* Aufrufen der Callbackliste f�r den Exposeevent */
909         XtCallCallbackList((Widget)cw,cw->histspectr.expose_callback,&call_value);
910  	 }
911 }
912 
913 
914 /* ======================================================================= */
915 
916 
917 /***************************************************************************
918  ***************************************************************************
919  *
920  *  Functionname:	Resize
921  *
922  *
923  *  Prototype:	static void Resize ( Widget w );
924  *
925  *  Input:		Widget w
926  *
927  *  Output:
928  *
929  *  Return:
930  *
931  *  Documentation:	This is a method, called by X whenever the size
932  *			of widget was changed. it recreates the pixmaps for
933  *			the new size.
934  *
935  *
936  *  History:		Sun Jan 18 08:51:44 CET 1998
937  *                      Tue Dec 16 13:27:10 CET 2003
938  *
939  ***************************************************************************
940  ***************************************************************************/
941 
Resize(Widget w)942 static void Resize ( Widget w ){
943 
944   XwHistspectrWidget cw = (XwHistspectrWidget) w;
945   Dimension width,height;
946   XwHistspectrCallbackStruct call_value;
947 
948 	XFreePixmap(XtDisplay(cw), cw->histspectr.pix);
949 	if(cw->histspectr.panno)
950     		XFreePixmap(XtDisplay(cw),cw->histspectr.panno);
951 
952             /* for safety, cannot be smaller */
953        if(cw->core.width < minsize)
954 		cw->core.width = minsize;
955        if(cw->core.height < minsize)
956 		cw->core.height = minsize;
957 
958   	 cw->histspectr.panno = (Pixmap)NULL;	/* preclear */
959    	 get_proportion( cw );		/* recalculate sizes and starting */
960     	 cw->histspectr.pix =XCreatePixmap(XtDisplay(cw),
961   		RootWindow(XtDisplay(cw), DefaultScreen(XtDisplay(cw))),
962   		cw->histspectr.pixwidth, cw->histspectr.pixheight,
963   		cw->core.depth);
964 /* pixmap for external annotation  */
965   	if(cw->histspectr.anflag ){
966 		height =  cw->histspectr.pixheight;
967  	      	width = cw->histspectr.annsiz;
968  	    	 if(width > 0 && height > 0)
969     	       		 cw->histspectr.panno = XCreatePixmap(XtDisplay(cw),
970   			       RootWindow(XtDisplay(cw), DefaultScreen(XtDisplay(cw))),
971   			       width, height,cw->core.depth);
972 	 }
973 	clear_histspectr(cw );
974 	cw->histspectr.Xpos =cw->histspectr.width;
975 	cw->histspectr.oldy = cw->histspectr.height;
976 	cw->histspectr.foldx = cw->histspectr.pixwidth  - cw->histspectr.width;
977 	scale(cw);
978  	drawgrid(cw );
979 
980      	cw->histspectr.gr[0] = cw->histspectr.prevgrid;
981 
982 	 if(cw->histspectr.resize_callback){
983    		call_value.reason =XmCR_RESIZE ;
984     		call_value.event =NULL;
985    		call_value.fd = -1;
986    		call_value.width = cw->histspectr.width;
987    		call_value.height = cw->histspectr.height;
988     /* Aufrufen der Callbackliste f�r den Exposeevent */
989    		XtCallCallbackList((Widget)cw,cw->histspectr.resize_callback,&call_value);
990  	 }
991 
992 }
993 
994 
995 
996 /***************************************************************************
997  ***************************************************************************
998  *
999  *  Functionname:		Destroy
1000  *
1001  *  Input:			Widget w
1002  *
1003  *  Return:
1004  *
1005  *  Documentation:	Method, called when the widget is destroyed
1006  *			(not called during termination and quitting
1007  *                      must clearly free all allocated storage
1008  *
1009  *  History:            Tue Dec 16 13:27:10 CET 2003
1010  *
1011  ***************************************************************************
1012  ***************************************************************************/
Destroy(Widget w)1013 static void Destroy(Widget w ){
1014   XwHistspectrWidget cw = (XwHistspectrWidget) w;
1015   int i=0;
1016   unsigned long colorpix[4];
1017 
1018   	XFreeGC(XtDisplay( cw), cw->histspectr.gc);
1019     	XFreeGC(XtDisplay( cw), cw->histspectr.anngc);
1020 
1021         if(cw->histspectr.background)
1022                 colorpix[i++] = cw->histspectr.background;
1023         if(cw->histspectr.anncolor)
1024                 colorpix[i++] = cw->histspectr.anncolor;
1025         if(cw->histspectr.fillcolor)
1026                 colorpix[i++] = cw->histspectr.fillcolor;
1027         if(cw->histspectr.linecolor)
1028                 colorpix[i++] = cw->histspectr.linecolor;
1029         if(i)
1030             XFreeColors(XtDisplay(cw), DefaultColormap(XtDisplay(cw)
1031 		,DefaultScreen(XtDisplay(cw))),colorpix,i,0);
1032 
1033 	/* XmFontListFree(cw->histspectr.font_list); */
1034 	XFreePixmap(XtDisplay(cw), cw->histspectr.pix);
1035 	if(cw->histspectr.panno)
1036 		XFreePixmap(XtDisplay(cw), cw->histspectr.panno);
1037 	if(cw->histspectr.curve)
1038             XtFree((char *)cw->histspectr.curve);
1039 	XtFree((char *)cw->histspectr.vis);
1040 	XtFree((char *)cw->histspectr.gr);
1041 	cw->histspectr.pix = 0;
1042 	cw->histspectr.panno = 0;
1043 	cw->histspectr.gc = NULL;
1044 	cw->histspectr.anngc = NULL;
1045 	/* cw->histspectr.font_list = NULL; */
1046 
1047 
1048 
1049 }
1050 /***************************************************************************
1051  ***************************************************************************
1052  *
1053  *  Functionname:	clear_histspectr
1054  *
1055  *
1056  *  Prototype:	static void clear_histspectr(XwHistspectrWidget cw );
1057  *
1058  *  Input:		XwHistspectrWidget cw , int notall
1059  *
1060  *  Output:
1061  *
1062  *  Return:
1063  *
1064  *  Documentation:	 actual clearing the total pixmap
1065  *			to background colour, should be followed by recreating grid
1066  *			(and scale)
1067  *
1068  *
1069  *  History:		Sun Jan 18 08:52:05 CET 1998
1070  *                      Tue Dec 16 13:27:10 CET 2003
1071  *
1072  ***************************************************************************
1073  ***************************************************************************/
clear_histspectr(XwHistspectrWidget cw)1074 static void clear_histspectr(XwHistspectrWidget cw ){
1075 
1076 
1077      	XSetForeground(XtDisplay(cw),cw->histspectr.gc,cw->histspectr.background);
1078 	XFillRectangle(XtDisplay(cw),cw->histspectr.pix,cw->histspectr.gc,
1079 		    0,0,cw->histspectr.pixwidth,cw->histspectr.pixheight);
1080 
1081 	if(cw->histspectr.panno){
1082      	    XSetForeground(XtDisplay(cw),cw->histspectr.anngc,cw->core.background_pixel);
1083  	    XFillRectangle(XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc,
1084 	        0,0,cw->histspectr.annsiz,cw->histspectr.pixheight);
1085 
1086       	    XSetForeground(XtDisplay(cw),cw->histspectr.anngc,cw->histspectr.anncolor);
1087         }
1088 }
1089 
1090 
1091 
1092 /***************************************************************************
1093  ***************************************************************************
1094  *
1095  *  Functionname:	scale
1096  *
1097  *
1098  *  Prototype:	static void scale(XwHistspectrWidget cw);
1099  *
1100  *  Input:		XwHistspectrWidget cw
1101  *
1102  *  Output:
1103  *
1104  *  Return:
1105  *
1106  *  Documentation:	does all scaling,construct parameters to calculate from users values
1107  *			into pixmap. *
1108  *		given vis[6]	vis[0]   xoffset starting value of time
1109  *				vis[1]   displayable x-range
1110  *				vis[2]   lowest y value
1111  *				vis[3]   range of y
1112  *                              vis[4]   min value of x-axis
1113  *                              vis[5]   range of x-axis
1114  *  History:	Tue Dec 16 13:21:24 CET 2003
1115  *
1116  *
1117  ***************************************************************************
1118  ***************************************************************************/
scale(XwHistspectrWidget cw)1119 static void scale(XwHistspectrWidget cw){
1120    double width,height;
1121  /* assumed, that pixel coords begin with 0 */
1122 
1123  /* basically we use a square as diaplay area, so the height will be used */
1124  	width  = (cw->histspectr.height / 2.0) / sin(cw->histspectr.angle);
1125  	height = cw->histspectr.height /2.0 ;
1126 
1127 	cw->histspectr.sc.bt =  width /  cw->histspectr.vis[1] ;
1128 
1129 
1130 	cw->histspectr.sc.by = height /  cw->histspectr.vis[3] ;
1131 	cw->histspectr.sc.ay =  - cw->histspectr.sc.by * cw->histspectr.vis[2];
1132 	cw->histspectr.sc.bx = width /  cw->histspectr.vis[5] ;
1133 	cw->histspectr.sc.ax =   cw->histspectr.sc.bx * cw->histspectr.vis[4];
1134 }
1135 
1136 
1137 
1138 /***************************************************************************
1139  ***************************************************************************
1140  *
1141  *  Functionname:	drawannot
1142  *
1143  *
1144  *  Prototype:	static void drawannot(XwHistspectrWidget  cw);
1145  *
1146  *  Input:		XwHistspectrWidget  cw
1147  *
1148  *  Output:
1149  *
1150  *  Return:
1151  *
1152  *  Documentation:	draws the ordinate annotation(if needed) to window
1153  *
1154  *
1155  *  History:	Mon Jan  5 10:15:22 CET 1998
1156  *              Tue Dec 16 13:27:10 CET 2003
1157  *
1158  ***************************************************************************
1159  ***************************************************************************/
drawannot(XwHistspectrWidget cw)1160 static void drawannot(XwHistspectrWidget  cw){
1161    int ypix  , cnt = cw->histspectr.ynthgridanno+1;
1162    int len,cheight =  (cw->histspectr.font_struct->ascent - cw->histspectr.font_struct->descent);
1163    int cnt1 = cw->histspectr.xnthgridanno+1;
1164    int  pos=0 ;
1165    float base = cw->histspectr.gr[2]  ;
1166    char annot[40];
1167 
1168 
1169       	if(!cw->histspectr.anflag)
1170       			return;
1171 
1172         XSetForeground(XtDisplay(cw),cw->histspectr.anngc
1173 		    ,cw->histspectr.anncolor);
1174        while((ypix= cw->histspectr.height -
1175                 (cw->histspectr.sc.ay + cw->histspectr.sc.by * base))
1176                 >= cw->histspectr.height/2  ) {   	/* ordinate annot */
1177   		      /* ypix = cw->histspectr.height -  (cw->histspectr.sc.ay + cw->histspectr.sc.by * base); */
1178 
1179       		     if(ypix <= (cw->histspectr.height - cheight/2)  ){
1180        		          if(!--cnt ){
1181        			     cnt = cw->histspectr.ynthgridanno+1;
1182        			     sprintf(annot,"%.*f",cw->histspectr.yndecimals,base);
1183        			     len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) ;
1184      			        pos = cw->histspectr.xv - len -8	;
1185        			     XDrawString (XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc
1186        			        ,pos , ypix+cheight/2 ,annot,strlen(annot));
1187       			  }
1188       		     }
1189       		     XDrawLine(XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc
1190       		         , cw->histspectr.xv , ypix,cw->histspectr.xv -8 ,ypix);
1191       		     base += cw->histspectr.gr[3];
1192       	}
1193                     /* do annotation of X-axis  */
1194         base = cw->histspectr.gr[4];
1195         while((pos = cw->histspectr.xv + cw->histspectr.sc.ax + cw->histspectr.sc.bx *base)
1196                  < (cw->histspectr.width )){
1197            if(pos < 0)
1198                break;
1199            XDrawLine(XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc
1200       		         , pos , cw->histspectr.height,pos ,cw->histspectr.height+ cheight);
1201        	   if(!--cnt1 ){
1202        		cnt1 = cw->histspectr.xnthgridanno+1;
1203        		sprintf(annot,"%.*f",cw->histspectr.xndecimals,base);
1204        		len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) ;
1205        		XDrawString (XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc
1206        			,pos-len/2 , cw->histspectr.height  + 2*cheight ,annot,strlen(annot));
1207       	  }
1208           base += cw->histspectr.gr[5];
1209        }
1210      	if(!cw->histspectr.dofixtext)
1211 	    return;
1212 
1213 	    	    /* now add the fixtext per bar  */
1214 	ypix = (cw->histspectr.height + 2 ) +( 3 * cheight  );
1215 	if(cw->histspectr.fixtext){
1216 	    	XSetForeground(XtDisplay(cw),cw->histspectr.anngc
1217 		    ,cw->histspectr.anncolor);
1218 	  	pos = cw->histspectr.xv /* + cw->histspectr.Xpos - cw->histspectr.width */;
1219 		XDrawString (XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc
1220        		    	,pos , ypix  ,cw->histspectr.fixtext
1221 		    	,strlen(cw->histspectr.fixtext));
1222 	}
1223 
1224   }
1225 
1226 
1227 /***************************************************************************
1228  ***************************************************************************
1229  *
1230  *  Functionname:	drawgrid
1231  *
1232  *
1233  *  Prototype:	static void drawgrid(XwHistspectrWidget cw );
1234  *
1235  *  Input:		XwHistspectrWidget cw , int doit
1236  *
1237  *  Output:
1238  *
1239  *  Return:
1240  *
1241  *  Documentation:
1242  *			Draws the grid into pixmap and draws the time
1243  *			annotation  into annotation pixmap
1244  *
1245  *
1246  *  History:		Mon Jan  5 11:19:36 CET 1998
1247  *                      Tue Dec 16 13:27:10 CET 2003
1248  *
1249  ***************************************************************************
1250  ***************************************************************************/
drawgrid(XwHistspectrWidget cw)1251 static void drawgrid(XwHistspectrWidget cw){
1252    int ypix , cnt = cw->histspectr.lastanncnt , len;
1253    float base = cw->histspectr.gr[0] ;
1254    char annot[40];
1255 
1256    int cheight =  (cw->histspectr.font_struct->ascent - cw->histspectr.font_struct->descent);
1257 
1258     	if(!cw->histspectr.panno)
1259 	    return;
1260 /*    grid forground colour is fixed set to cw->primitive.foreground    */
1261       	XSetForeground(XtDisplay(cw),cw->histspectr.anngc,cw->core.background_pixel);
1262   	XFillRectangle(XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc,
1263 		    0,0,cw->histspectr.annsiz,cw->histspectr.pixheight);
1264       	XSetForeground(XtDisplay(cw),cw->histspectr.anngc,cw->histspectr.anncolor);
1265 /* do y- rastering */
1266 	cw->histspectr.prevgrid = cw->histspectr.gr[0];   /* save for repeat gridding */
1267       	while((ypix= cw->histspectr.height +
1268  		 (base - cw->histspectr.sc.at ) *
1269 	 	 cw->histspectr.sc.bt * sin(cw->histspectr.angle)) >= 0) {   	/* time grid first up*/
1270       	    if(ypix+cheight/2  <= cw->histspectr.height ){
1271 
1272       	        if(!--cnt ){
1273                     cnt = cw->histspectr.tnthgridanno+1;
1274        	            sprintf(annot,"%.*f",cw->histspectr.tndecimals,base);
1275        	            len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) ;
1276 
1277        	            XDrawString (XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc
1278        		        ,cw->histspectr.annsiz - len  , ypix+cheight/2 ,annot,strlen(annot));
1279 	        }
1280             }
1281   	    XDrawLine(XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc
1282       				 ,0,ypix,8,ypix);
1283       	    base -= cw->histspectr.gr[1];
1284       	}
1285    	base = cw->histspectr.gr[0] ;
1286         while((ypix = cw->histspectr.height +
1287 		(base - cw->histspectr.sc.at ) *
1288 	 	cw->histspectr.sc.bt * sin(cw->histspectr.angle))
1289                     <= (cw->histspectr.pixheight - cheight/2))  {   	/* time grid second down*/
1290 
1291       	    if( ypix >= 0){
1292      	        if(!--cnt ){
1293        	            cnt = cw->histspectr.tnthgridanno+1;
1294        	            sprintf(annot,"%.*f",cw->histspectr.tndecimals,base);
1295        	            len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot)) ;
1296 
1297        	            XDrawString (XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc
1298        		         ,cw->histspectr.annsiz - len , ypix+cheight/2
1299        		        ,annot,strlen(annot));
1300 
1301 	        }
1302         }
1303       	    XDrawLine(XtDisplay(cw),cw->histspectr.panno,cw->histspectr.anngc
1304       		,0,ypix,8,ypix);
1305       	    base += cw->histspectr.gr[1];
1306       	}
1307    	cw->histspectr.lastanncnt = cnt;
1308 
1309 }
1310 
1311 
1312 
1313 /***************************************************************************
1314  ***************************************************************************
1315  *
1316  *  Functionname:		 copyannot
1317  *
1318  *  Input:			XwHistspectrWidget  cw , Drawable target,double yoffset
1319  *
1320  *  Return:
1321  *
1322  *  Documentation:      if external annotation set, copies the annotation pixmap
1323  *			in place for annotation, wher given might be x or y coordinate
1324  *			corresponding to direction
1325  *
1326  *
1327  *  History:		Wed Mar 12 17:45:42 CET 1997
1328  *                      Tue Dec 16 13:27:10 CET 2003
1329  *
1330  ***************************************************************************
1331  ***************************************************************************/
copyannot(XwHistspectrWidget cw,Drawable target,double yoffset)1332 static void  copyannot(XwHistspectrWidget  cw , Drawable target , double yoffset){
1333 
1334   	if(!cw->histspectr.panno)
1335   		return;		/* no copy needed */
1336   	XCopyArea(XtDisplay(cw),cw->histspectr.panno,target,
1337   		        cw->histspectr.anngc,   0 ,(int)yoffset
1338   		         , cw->histspectr.annsiz, cw->histspectr.height
1339   		         ,cw->histspectr.xv+cw->histspectr.width,0);
1340 }
1341 
1342 /***************************************************************************
1343  ***************************************************************************
1344  *
1345  *  Functionname:		 copypix
1346  *
1347  *  Input:			XwHistspectrWidget  cw
1348  *
1349  *  Return:
1350  *
1351  *  Documentation:		copies the actual pixmapwindow into visible
1352  *			if external annotation set, copies the annotation pixmap
1353  *			in place for annotation.
1354  *
1355  *  History:		Sat Jan  3 09:26:31 CET 1998
1356  *                      Tue Dec 16 13:27:10 CET 2003
1357  *
1358  ***************************************************************************
1359  ***************************************************************************/
copypix(XwHistspectrWidget cw)1360 static void  copypix(XwHistspectrWidget  cw ){
1361   double lsttim = 0;
1362         if(cw->histspectr.foldy > 0
1363   		|| cw->histspectr.foldx < cw->histspectr.pixwidth - cw->histspectr.width){
1364 	    if(cw->histspectr.foldy > cw->histspectr.Yoffset)
1365   		cw->histspectr.Yoffset = cw->histspectr.foldy;
1366 	    if(cw->histspectr.foldx < cw->histspectr.Xoffset)
1367   		cw->histspectr.Xoffset = cw->histspectr.foldx;
1368   	    if(lsttim < cw->histspectr.lasttim)
1369   				lsttim = cw->histspectr.lasttim;
1370   	}
1371         XCopyArea(XtDisplay(cw),cw->histspectr.pix,XtWindow(cw),
1372   	    	cw->histspectr.gc, (int)cw->histspectr.Xoffset  , (int)cw->histspectr.Yoffset
1373   	    	, cw->histspectr.width, cw->histspectr.height,cw->histspectr.xv,0);
1374 
1375         copyannot(cw ,XtWindow(cw),cw->histspectr.Yoffset );
1376         dancevals(cw);
1377 	if(cw->histspectr.Xoffset <= 10
1378 	      || cw->histspectr.Yoffset >= (cw->histspectr.pixheight -cw->histspectr.height -10)){
1379 		/* now refresh pixmap */
1380 		XCopyArea(XtDisplay(cw),cw->histspectr.pix,cw->histspectr.pix
1381 		  , cw->histspectr.gc, (int)cw->histspectr.Xoffset  , (int)cw->histspectr.Yoffset
1382 		  ,cw->histspectr.width, cw->histspectr.height
1383 		  ,cw->histspectr.pixwidth - cw->histspectr.width,0);
1384 		cw->histspectr.Xoffset  =  cw->histspectr.pixwidth - cw->histspectr.width;
1385 		cw->histspectr.Yoffset = 0;/* cw->histspectr.height; */
1386 		cw->histspectr.oldx = cw->histspectr.pixwidth - cw->histspectr.width;
1387 		cw->histspectr.oldy = cw->histspectr.foldy =  0 ;
1388 		cw->histspectr.foldx = cw->histspectr.oldx ;
1389 		XSetForeground(XtDisplay(cw),cw->histspectr.gc,cw->histspectr.background);
1390   		XFillRectangle(XtDisplay(cw),cw->histspectr.pix , cw->histspectr.gc,
1391 		     0,0, cw->histspectr.pixwidth - cw->histspectr.width , cw->histspectr.pixheight);
1392 		XFillRectangle(XtDisplay(cw),cw->histspectr.pix , cw->histspectr.gc,
1393 		     cw->histspectr.pixwidth - cw->histspectr.width ,    cw->histspectr.height
1394 		      ,cw->histspectr.width, cw->histspectr.pixheight -  cw->histspectr.height);
1395 		cw->histspectr.sc.at =  lsttim;
1396 		drawgrid(cw);
1397 	}
1398 
1399 }
1400 
1401 
1402 
1403 
1404 /***************************************************************************
1405  ***************************************************************************
1406  *
1407  *  Functionname:		drawspectr
1408  *
1409  *  Input:			XwHistspectrWidget cw
1410  *			 long int id		id of actual bar
1411  *			float val , float time      	values of bar
1412  *
1413  *  Output:
1414  *
1415  *  Return:
1416  *
1417  *  Documentation:      draws a bar into pixmap, saving the actual values for next
1418  *			draw. The deepness of bar is calculated from previous time
1419  *
1420  *   On host:		wizant			by: WizAnt Software
1421  *  History:		Sat Jan  3 09:26:15 CET 1998
1422  *                      Tue Dec 16 13:27:10 CET 2003
1423  *
1424  ***************************************************************************
1425  ***************************************************************************/
drawspectr(XwHistspectrWidget cw,w3dPoint * val,float time,int npoints)1426 static void drawspectr (XwHistspectrWidget cw,   w3dPoint *val , float time , int npoints){
1427 
1428 /* XPoint curve[540]; */
1429   int i ;
1430   char annot[20];
1431   int cheight =  (cw->histspectr.font_struct->ascent - cw->histspectr.font_struct->descent);
1432 
1433         cw->histspectr.mark = 0;
1434 	if(time < cw->histspectr.lasttim)
1435 			return;		/* x-axis must increase */
1436         if(!cw->histspectr.curve){
1437             cw->histspectr.curve = (XPoint *)XtMalloc(sizeof(XPoint)*(npoints+2));
1438             if(!cw->histspectr.curve ){
1439                 XtWarning("WHistspectr drawspectr cannot XtMalloc");
1440                 return;
1441             }
1442             cw->histspectr.curvepoint = npoints+2;
1443         }
1444         if(cw->histspectr.curvepoint < npoints+2 ){
1445             XtFree((char *)cw->histspectr.curve);
1446             cw->histspectr.curve = (XPoint *)XtMalloc(sizeof(XPoint)*(npoints+2));
1447             if(!cw->histspectr.curve ){
1448                 XtWarning("WHistspectr drawspectr cannot XtMalloc");
1449                 return;
1450             }
1451         }
1452 	if((time - cw->histspectr.lasttim	) >  (cw->histspectr.vis[0] + cw->histspectr.vis[1])){
1453 		fprintf(stderr," time is out of scale:  prevtime / time %f %f   %f\n"
1454 		,cw->histspectr.lasttim,time , cw->histspectr.vis[1]);
1455 
1456 			  /* ignoring is not the best, think about something intelligent */
1457 	}
1458 
1459 	cw->histspectr.foldx = (cw->histspectr.pixwidth - cw->histspectr.width) -
1460 		(time - cw->histspectr.sc.at ) *
1461 	 	cw->histspectr.sc.bt * cos(cw->histspectr.angle);
1462 	cw->histspectr.foldy =
1463  		(time - cw->histspectr.sc.at ) *
1464 		 cw->histspectr.sc.bt * sin(cw->histspectr.angle);
1465 	if(cw->histspectr.foldx > cw->histspectr.pixwidth
1466 		|| cw->histspectr.foldx < 0
1467 		||  cw->histspectr.height +cw->histspectr.foldy < 0
1468 		||  cw->histspectr.height +cw->histspectr.foldy > cw->histspectr.pixheight){
1469 	}
1470 	cw->histspectr.oldx = cw->histspectr.foldx;
1471 	cw->histspectr.oldy = cw->histspectr.foldy;
1472 
1473         for(i=1;i <= npoints;i++){
1474             cw->histspectr.curve[i].y = cw->histspectr.height +cw->histspectr.foldy-
1475                     (cw->histspectr.sc.ay + cw->histspectr.sc.by * val[i-1].y);
1476             cw->histspectr.curve[i].x =  cw->histspectr.Xpos + cw->histspectr.foldx - cw->histspectr.width
1477                     +(cw->histspectr.sc.ax + cw->histspectr.sc.bx *val[i-1].x) ;
1478             if(cw->histspectr.marker && i > 1 && val[i-2].x <= cw->histspectr.marker
1479                     && val[i].x >=  cw->histspectr.marker)
1480                 cw->histspectr.mark = i;
1481         }
1482         cw->histspectr.curve[npoints+1].y  =  cw->histspectr.curve[0].y  =  cw->histspectr.height +cw->histspectr.foldy;
1483         cw->histspectr.curve[0].x =  cw->histspectr.curve[1].x;
1484         cw->histspectr.curve[npoints+1].x = cw->histspectr.curve[i-1].x;
1485 	XSetForeground(XtDisplay(cw), cw->histspectr.gc,cw->histspectr.fillcolor);
1486 
1487         XFillPolygon(XtDisplay(cw),cw->histspectr.pix , cw->histspectr.gc, cw->histspectr.curve
1488 			, npoints+2, Nonconvex, CoordModeOrigin);
1489 
1490     	XSetForeground(XtDisplay(cw), cw->histspectr.gc,cw->histspectr.linecolor);
1491 /*  Lines or Points the Question */
1492         if(cw->histspectr.lines)
1493             XDrawLines(XtDisplay(cw), cw->histspectr.pix, cw->histspectr.gc
1494                 , &cw->histspectr.curve[1],npoints,CoordModeOrigin);
1495         else
1496             XDrawPoints(XtDisplay(cw), cw->histspectr.pix, cw->histspectr.gc
1497                 , &cw->histspectr.curve[1],npoints,CoordModeOrigin);
1498 	cw->histspectr.lasttim = time;
1499         if(cw->histspectr.mark )        /* draw a marker line at given x-pos */
1500             XDrawLine (XtDisplay(cw), cw->histspectr.pix, cw->histspectr.anngc
1501                , cw->histspectr.curve[cw->histspectr.mark].x
1502                , cw->histspectr.height+cw->histspectr.Yoffset-cheight
1503                , cw->histspectr.curve[cw->histspectr.mark].x , cw->histspectr.curve[cw->histspectr.mark].y-10);
1504 
1505 }
1506 
1507 
1508 /***************************************************************************
1509  ***************************************************************************
1510  *
1511  *  Functionname:		dancevals
1512  *
1513  *  Input:			XwHistspectrWidget  cw
1514  *
1515  *  Return:
1516  *
1517  *  Documentation:	plots marker x-value above copied pixmap
1518  *
1519  *
1520  *  History:		Mon Dec 15 14:20:46 CET 2003
1521  *
1522  *
1523  ***************************************************************************
1524  ***************************************************************************/
dancevals(XwHistspectrWidget cw)1525 static void  dancevals(XwHistspectrWidget  cw ){
1526   int i , xpix,ypix ;
1527   int len , pos;
1528   char annot[20];
1529 
1530         if(cw->histspectr.mark ){
1531              sprintf(annot,"%.*f",cw->histspectr.xndecimals,cw->histspectr.marker);
1532             len = XTextWidth(cw->histspectr.font_struct,annot,strlen(annot))/2 ;
1533             pos = cw->histspectr.curve[cw->histspectr.mark].x - cw->histspectr.Xoffset+cw->histspectr.xv-len;
1534             if(pos < cw->histspectr.xv)  /* avoid plotting outside */
1535                 pos = cw->histspectr.xv;
1536             XDrawString (XtDisplay(cw), XtWindow(cw),cw->histspectr.anngc
1537        		,pos,cw->histspectr.height-3 ,annot,strlen(annot));
1538 
1539         }
1540 
1541  }
1542 
1543 
1544 /* ================================================================================ */
1545 /*		Public directly accessible Functions */
1546 /* ================================================================================ */
1547 
1548 
1549 /***************************************************************************
1550  ***************************************************************************
1551  *
1552  *  Functionname:		XwCreateHistspectr
1553  *
1554  *  Input:			Widget parent,
1555  *			 char *name,
1556  *			ArgList arglist,
1557  *			Cardinal argcount
1558  *
1559  *  Return:		 Widget
1560  *
1561  *  Documentation:		Standeard X- creating routine
1562  *
1563  *
1564  *  History:		Sun Jan 18 08:55:04 CET 1998 on host:wizant
1565  *			Tue Dec 16 13:27:10 CET 2003
1566  *
1567  *
1568  ***************************************************************************
1569  ***************************************************************************/
XwCreateHistspectr(Widget parent,char * name,ArgList arglist,Cardinal argcount)1570  Widget XwCreateHistspectr( Widget parent, char *name,  ArgList arglist
1571                              , Cardinal argcount) {
1572 
1573 
1574    return( (Widget) XtCreateWidget(name, XwHistspectrWidgetClass, parent, arglist, argcount));
1575 
1576  }
1577 
1578 
1579 
1580 /***************************************************************************
1581  ***************************************************************************
1582  *
1583  *  Functionname:		XwHistspectrSettext
1584  *
1585  *  Input:			Widget w
1586  *			char *text	set text to display (empty or NULL to rest)
1587  *
1588  *  Return:
1589  *
1590  *  Documentation:		sets the per bar text display.
1591  *			    CAUTION: There is no limit check for number of characters
1592  *  	    	    	    so check if the text fits with fontsize into one line
1593  *
1594  *
1595  *  History:		Sun Jan 25 08:05:44 CET 1998
1596  *                      Tue Dec 16 13:27:10 CET 2003
1597  ***************************************************************************
1598  ***************************************************************************/
XwHistspectrSettext(Widget w,char * text)1599 void XwHistspectrSettext(Widget w,  char *text){
1600   XwHistspectrWidget cw = (XwHistspectrWidget) w;
1601 
1602         if(!XwIsHistspectr(w)){
1603 		XtWarning("BAD widget id in XwHistspectrSettext");
1604 		return;
1605 	}
1606 
1607 	if(cw->histspectr.fixtext)
1608 		free(cw->histspectr.fixtext);
1609 	if(!text || !strlen(text) ){
1610 		cw->histspectr.fixtext = NULL;
1611                 cw->histspectr.dofixtext = FALSE;
1612 		return;
1613 	}
1614 	cw->histspectr.fixtext = strdup(text);
1615         cw->histspectr.dofixtext = TRUE;
1616 	if(cw->histspectr.dofixtext && cw->histspectr.exposed)
1617 	    drawannot(cw);
1618 
1619 
1620 }
1621 
1622 
1623 /***************************************************************************
1624  ***************************************************************************
1625  *
1626  *  Functionname:		XwHistdoscan
1627  *
1628  *  Input:		Widget    w 	target histspectring widget
1629  *
1630  *			w3dPoint xy[]		value pair (x , y )
1631  *			int npoints
1632  *                      float time              t-axis value
1633  *  Return:
1634  *
1635  *  Documentation:	adds a scan to the actual display
1636  *
1637  *
1638  *  History:		Sun Jan 18 08:56:47 CET 1998 on host: wizant
1639  *                      Tue Dec 16 13:27:10 CET 2003
1640  *
1641  ***************************************************************************
1642  ***************************************************************************/
XwHistdoscan(Widget w,w3dPoint xy[],int npoints,float time)1643  void XwHistdoscan (Widget    w  ,  w3dPoint xy[] ,int npoints , float time){
1644    XwHistspectrWidget cw = (XwHistspectrWidget) w;
1645    float min = 900000000.0, max = -900000000.0 ;
1646    int i , rescale =0;
1647 
1648         if(!XwIsHistspectr(w)){
1649 		XtWarning("BAD widget id in XwHistdoscan");
1650 		return;
1651 	}
1652  /* if autoscale is set do the scaling and gridding  */
1653        if(cw->histspectr.autoscale & AutoTime ){   /*autotiming */
1654             if(!cw->histspectr.lasttim){
1655                 cw->histspectr.lasttim = time;
1656                 return;                            /* delay it now for next sample */
1657             }
1658             cw->histspectr.vis[1] = (time - cw->histspectr.lasttim)*100.0;
1659             cw->histspectr.gr[0] = cw->histspectr.lasttim;
1660             cw->histspectr.gr[1] = cw->histspectr.vis[1] / 5;
1661             rescale++;
1662         }
1663         if(cw->histspectr.autoscale & AutoAbs){   /* abscissa */
1664             for(i=0;i<npoints;i++){
1665                 if(min > xy[i].x)
1666                     min =  xy[i].x;
1667                 if(max <  xy[i].x)
1668                     max = xy[i].x;
1669             }
1670             cw->histspectr.vis[4]=min;
1671             cw->histspectr.vis[5]= max-min;
1672             if(!cw->histspectr.vis[5])
1673                 return;       /* unusable, scale later */
1674             cw->histspectr.gr[4] = min;
1675             cw->histspectr.gr[5] = cw->histspectr.vis[5] / 5.0;
1676             rescale++;
1677         }
1678         if(cw->histspectr.autoscale & AutoAmpl){   /* Aplitude */
1679             min =  900000000.0;
1680             max = -900000000.0;
1681             for(i=0;i<npoints;i++){
1682                 if(min > xy[i].y)
1683                     min =  xy[i].y;
1684                 if(max <  xy[i].y)
1685                     max = xy[i].y;
1686             }
1687             cw->histspectr.vis[3] = max-min;
1688             if(!cw->histspectr.vis[3])
1689                 return;       /* unusable, scale later */
1690             cw->histspectr.vis[2] = min - cw->histspectr.vis[3] *2 ;
1691             cw->histspectr.vis[3] *= 4.0;
1692             cw->histspectr.gr[2] = cw->histspectr.vis[2];
1693             cw->histspectr.gr[3] = cw->histspectr.vis[3] / 5.0;
1694             rescale++;
1695         }
1696 
1697         if(rescale){
1698 	    scale(cw);	/* scale the widget */
1699 	    drawgrid(cw );
1700             XSetForeground(XtDisplay(cw),cw->histspectr.anngc
1701 		    ,cw->core.background_pixel);
1702   	    XFillRectangle(XtDisplay(cw),XtWindow(cw),cw->histspectr.anngc,
1703 		    0,0,cw->core.width,cw->core.height);
1704             drawannot(cw );
1705             cw->histspectr.autoscale &= ~(AutoAbs|AutoAmpl|AutoTime);
1706         }
1707 
1708 
1709  /*  first check if pixmap overrun will occur, than refresh pixmap */
1710 
1711 	drawspectr (cw,   xy , time , npoints);
1712 
1713  	cw->histspectr.lasttim = time;
1714     	copypix(cw );
1715  }
1716 
1717 
1718 
1719 
1720 /***************************************************************************
1721  ***************************************************************************
1722  *
1723  *  Functionname:		XwHistspectrSetMarker
1724  *
1725  *  Input:		Widget    w 	target histspectring widget
1726  *
1727  *			float x		abscissa value to mark monitoring
1728  *  Return:
1729  *
1730  *  Documentation:	adds a scan to the actual display
1731  *
1732  *
1733  *  History:		Tue Dec 16 13:27:10 CET 2003
1734  *
1735  *
1736  ***************************************************************************
1737  ***************************************************************************/
XwHistspectrSetMarker(Widget w,float x)1738 void  XwHistspectrSetMarker (Widget w ,float x){
1739         if(!XwIsHistspectr(w)){
1740 		XtWarning("BAD widget id in XwHistspectrSetMarker");
1741 		return;
1742 	}
1743         ((XwHistspectrWidget) w)->histspectr.marker = x;
1744 }
1745 #ifdef __cplusplus
1746  }
1747 #endif
1748