1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 #if defined(HAVE_STRING_H)
12 #include <string.h>
13 #endif
14 
15 #include "interact.h"
16 #include "separate.h"
17 #include "plot.h"
18 
19 static Error _dxfgetdelta(method_type,float ,float ,float *);
20 static Error getdec(float ,float ,float ,int *);
21 
_dxfinteract_float(char * id,Object idobj,float * min,float * max,float * incr,int * decimal,char * label,int pos,method_type method,int * items,int iprint[])22 Error _dxfinteract_float(char *id, Object idobj, float *min, float *max,
23            float *incr, int *decimal, char *label, int pos,
24 	   method_type method, int *items, int iprint[])
25 {
26    int i;
27    Array temp;
28    float *old;
29 
30    Private p;
31    char *cache_label = NULL;
32    char *old_label;
33 
34    for (i=0; i<MAXPRINT; i++)
35      iprint[i]=0;
36 
37    cache_label = (char *)DXAllocate(strlen(id) + 32);
38    if (! cache_label)
39        goto error;
40 
41    /*  set cache entry for min,max,inc,decimal */
42    strcpy(cache_label,id);
43    strcat(cache_label,"_array");
44 
45    temp = (Array)DXGetCacheEntry(cache_label,pos,1,idobj);
46    if (!temp)
47    {
48       temp =DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, MAXPRINT-2);
49         old = (float *)DXGetArrayData(temp);
50 
51       old[0] = DXD_MAX_FLOAT;
52       old[1] = -DXD_MAX_FLOAT;
53       old[2] = DXD_MAX_FLOAT;
54       old[3] = -1;
55       old[4] = -1;
56 
57       if (incr && method!=ABSOLUTE){
58          if (!_dxfgetdelta(method,*min,*max,incr))
59             goto error;
60       }
61       if (decimal && *decimal==DXD_MAX_INT){
62          if (!getdec(*min,*max,*incr,decimal))
63             goto error;
64       }
65 
66 
67       if(temp){
68         DXReference((Object)temp);
69         if (!DXSetCacheEntry((Object)temp,CACHE_PERMANENT,cache_label,pos,1,\
70                               idobj))
71            DXErrorGoto(ERROR_INTERNAL,"can't set cache");
72       }
73    }
74    else{
75 
76         old = (float *)DXGetArrayData(temp);
77         DXDelete((Object)temp);
78         if (*min==DXD_MAX_FLOAT) *min=old[0];
79         if (*max==-DXD_MAX_FLOAT) *max=old[1];
80         if (incr && method!=ABSOLUTE){
81            if (!_dxfgetdelta(method,*min,*max,incr))
82               goto error;
83         }
84         if (decimal && *decimal==DXD_MAX_INT){
85            if (!getdec(*min,*max,*incr,decimal))
86               goto error;
87         }
88         /* DXWarning("min,max,incr,%g,%g,%g",*min,*max,*incr);*/
89    }
90 
91    /* set cache for label */
92    strcpy(cache_label,id);
93    strcat(cache_label,"_label");
94 
95    p = (Private)DXGetCacheEntry(cache_label,0,1,idobj);
96    if (!p){
97       old_label = (char *)DXAllocate(41);
98       if (!old_label)
99           goto error;
100       iprint[5]=1;
101       strcpy(old_label,"j");
102       p = DXNewPrivate(old_label,NULL);
103       strncpy(DXGetPrivateData(p),label,40);
104       if (p){
105          DXReference((Object)p);
106          if (!DXSetCacheEntry((Object)p,CACHE_PERMANENT,cache_label,0,1,idobj))
107             DXErrorGoto(ERROR_INTERNAL,"can't set cache");
108       }
109    }
110 
111    else{
112 
113       if (strcmp(label,DXGetPrivateData(p))){
114         iprint[5]=1;
115         strncpy(DXGetPrivateData(p),label,40);
116 
117       }
118    }
119 
120 
121 
122    /* Print out the message
123     * min,max,incr,decimal if different than cached values
124     */
125 
126    if (old[0]!=*min)
127      iprint[0]=1;
128    if (old[1]!=*max)
129      iprint[1]=1;
130    if (incr && old[2]!=*incr)
131      iprint[2]=1;
132    if (decimal && old[3]!=*decimal)
133      iprint[3]=1;
134    if (items && old[4]!=*items)
135      iprint[6]=1;
136 
137    old[0] = *min;
138    old[1] = *max;
139    if (incr)
140       old[2] = *incr;
141    else
142       old[2] = 0;
143    if (decimal)
144       old[3] = *decimal;
145    else
146       old[3] = 0;
147    if (items)
148       old[4] = *items;
149    else
150       old[4] = 0;
151    if (!DXAddArrayData(temp, 0,MAXPRINT-2,old))
152        DXErrorGoto(ERROR_INTERNAL,"can't get array data");
153 
154    DXFree(cache_label);
155    return OK;
156 
157 error:
158    DXFree(cache_label);
159    return ERROR;
160 }
161 
_dxfnewvalue(float * value,float old_min,float old_max,float min,float max,int remap,int * ip)162 Error _dxfnewvalue(float *value, float old_min, float old_max,
163                    float min, float max, int remap,int *ip)
164 {
165    float valtemp;
166 
167    if (old_min==DXD_MAX_FLOAT) remap=0;
168 
169    if (remap==1){
170       if (*value == old_min)
171 	  valtemp = min;
172       else if (*value == old_max)
173 	  valtemp = max;
174       else if ((old_max-old_min)!=0)
175           valtemp=(max-min)*(1.0-((old_max-*value)/(old_max-old_min))) +min;
176       else
177         valtemp = min;
178    }
179    else
180      valtemp = CLAMP(*value,min,max);
181 
182    if (*value!=valtemp) *ip=1;
183    *value = valtemp;
184 
185    return OK;
186 }
187 
_dxfprint_message(Pointer dp,struct einfo * ep,Type type,int rank,int * dim,int item)188 Error _dxfprint_message(Pointer dp, struct einfo *ep, Type type, int rank,
189         int *dim, int item)
190 {
191    int i,j,k;
192    int rank1,offset=0;
193    char c;
194 
195    if (rank == 0) rank1 = 1;  /* if scalar set count to 1 */
196    else rank1 = rank;
197 
198    if (item>1) {sprintf(ep->mp,"{"); ep->mp++;}
199    for (i=0; i<item; i++){
200      if (rank>=1){
201       if (type==TYPE_STRING) {sprintf(ep->mp,"\""); ep->mp++;}
202       else {sprintf(ep->mp,"["); ep->mp++;}
203    }
204     for (k=0; k<rank1; k++){
205      if (rank > 1) {sprintf(ep->mp,"["); ep->mp++;}
206      switch(type){
207       case TYPE_INT:
208         for (j=0; j<dim[k]; j++){
209          sprintf(ep->mp,"%d ",((int *)dp)[offset]); while(*ep->mp) ep->mp++;
210 	 offset++;
211 	}
212       break;
213       case TYPE_FLOAT:
214         for (j=0; j<dim[k]; j++){
215          sprintf(ep->mp,"%.8g ",((float *)dp)[offset]);while(*ep->mp) ep->mp++;
216 	 offset++;
217 	}
218       break;
219       case TYPE_STRING:
220         if ((dim[k] + ep->mp - ep->msgbuf) >= ep->maxlen) {
221 	  DXSetError(ERROR_INTERNAL,"too many items in list");
222           return ERROR;
223 	}
224         for (j=0; j<dim[k]; j++){
225 	   c = ((char *)dp)[offset];
226            switch(c) {
227 	      case '%':  sprintf(ep->mp,"%%%%");   break; /* the printf conversion char */
228 #ifndef DXD_NO_ANSI_ALERT
229 	      case '\a': sprintf(ep->mp,"\\a");  break; /* attention (bell) */
230 #endif
231 	      case '\b': sprintf(ep->mp,"\\b");  break; /* backspace */
232 	      case '\f': sprintf(ep->mp,"\\f");  break; /* formfeed */
233 	      case '\n': sprintf(ep->mp,"\\n");  break; /* newline */
234 	      case '\r': sprintf(ep->mp,"\\r");  break; /* carriage return */
235 	      case '\t': sprintf(ep->mp,"\\t");  break; /* horizontal tab */
236 	      case '\v': sprintf(ep->mp,"\\v");  break; /* vertical tab */
237 	      case '\\': sprintf(ep->mp,"\\\\"); break; /* backslash */
238 	      case '"':  sprintf(ep->mp,"\\\""); break; /* double quote */
239 	      /* case '\0': sprintf(ep->mp,"\\0");  break;  NULL */
240 	      default:
241 		 sprintf(ep->mp,"%c",c);
242 	   }
243 	   while(*ep->mp) ep->mp++;
244 	   offset++;
245 	}
246       break;
247       default:
248          DXErrorReturn(ERROR_BAD_TYPE,"unsupported type");
249      }
250      if (rank > 1) {sprintf(ep->mp,"]"); ep->mp++;}
251     }
252 
253     if (rank>=1){
254      if (type==TYPE_STRING) {sprintf(ep->mp,"\""); ep->mp++;}
255      else {sprintf(ep->mp,"]"); ep->mp++;}
256     }
257     sprintf(ep->mp," "); ep->mp++;
258     if (EndCheck(ep))
259        return ERROR;
260   }
261   if (item>1) {sprintf(ep->mp,"}"); ep->mp++;}
262 
263      return OK;
264 }
265 
_dxfcheck_obj_cache(Object obj,char * id,int key,Object idobj)266 int _dxfcheck_obj_cache(Object obj,char *id,int key,Object idobj)
267 {
268    Object temp_obj;
269    int remap=0;
270    char *cache_label = NULL;
271 
272    cache_label = (char *)DXAllocate(strlen(id) + 32);
273    if (! cache_label)
274        goto error;
275 
276    strcpy(cache_label,id);
277    strcat(cache_label,"_object");
278 
279    temp_obj = DXGetCacheEntry(cache_label,key,1,idobj);
280    if (!temp_obj){
281       if (obj) remap=2;
282       /* DXWarning("object is new, %d,exist=%d",key,remap); */
283       temp_obj=obj;
284       DXSetCacheEntry(temp_obj,CACHE_PERMANENT,cache_label,key,1,idobj);
285    }
286    else{
287       if (obj!=temp_obj){
288          /* DXWarning("group object has changed,%d",key); */
289          remap=1;
290 	 DXDelete(temp_obj);
291          temp_obj=obj;
292          /* DXReference(temp_obj); */
293          DXSetCacheEntry(temp_obj,CACHE_PERMANENT,cache_label,key,1,idobj);
294       }
295       else
296        DXDelete(temp_obj);
297    }
298    /* DXDelete(temp_obj); */
299 
300    DXFree(cache_label);
301    return remap;
302 
303 error:
304    DXFree(cache_label);
305    return 0;
306 }
307 
EndCheck(struct einfo * ep)308 int EndCheck(struct einfo *ep)
309 {
310     if (ep->atend)
311         return 1;
312 
313     if ((ep->mp - ep->msgbuf) >= ep->maxlen) {
314         ep->atend = 1;
315         DXSetError(ERROR_DATA_INVALID,"msg too long");
316         return 1;
317     }
318 
319     return 0;
320 
321 }
322 
323 static
_dxfgetdelta(method_type method,float min,float max,float * incr)324 Error _dxfgetdelta(method_type method,float min, float max, float *incr)
325 {
326    int n=100,sub=0;
327    float delta=0,lo=0,fuzz;
328    char fmt[20];
329    float range,start=0;
330 
331    switch(method){
332     case(PERCENT_ROUND):
333       if (*incr>0){
334          range = max-min;
335          fuzz = *incr * .1;
336          n = (int)(1.0/ (*incr-fuzz));
337          _dxfaxes_delta(&start,&range,1,&n,&lo,&delta,fmt,&sub,0,0);
338          *incr=delta;
339       }
340       else
341          *incr=0;
342       break;
343     case(PERCENT):
344       delta = *incr *(max-min);
345       *incr = delta;
346       break;
347     default:
348       break;
349    }
350 
351    return OK;
352 }
353 
354 static
getdec(float min,float max,float incr,int * dec)355 Error getdec(float min,float max,float incr, int *dec)
356 {
357    float s;
358 
359    s = max-min;
360    /* always scientific notation */
361    if (s>1000000.0 || s<0.000001){
362      if (incr>0)
363         *dec =(int)(log10(s) +0.99999)-(int)(log10(incr) +0.99999);
364      else{
365         if (s==0.0)
366            *dec=0;
367         else
368            *dec = (int)log10(s);
369      }
370    }
371    else if (incr > 0.0 && incr < 1.0)
372      *dec =(int)( -log10(incr)+0.99999);
373    else if (incr == 0)
374      *dec = 5;
375    else
376      *dec = 0;
377 
378    if (*dec > 6) *dec = 6;
379    return OK;
380 }
381 
382