Merge remote-tracking branch 'origin/5.4'
[scilab.git] / scilab / modules / graphics / src / c / Plo2dn.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
4  * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
5  * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
8  *
9  * This file must be used under the terms of the CeCILL.
10  * This source file is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution.  The terms
12  * are also available at
13  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
14  *
15  */
16
17 /*------------------------------------------------------------------------
18  *    Graphic library
19  --------------------------------------------------------------------------*/
20 #include <stdio.h>
21 #include <string.h>
22 #include "math_graphics.h"
23 #include "PloEch.h"
24 #include "Plot2d.h"
25
26 #define spINSIDE_SPARSE
27 #include "../../sparse/includes/spConfig.h"
28
29 #include "SetProperty.h"
30 #include "DrawObjects.h"
31 #include "BuildObjects.h"
32 #include "Axes.h"
33 #include "BasicAlgos.h"
34 #include "sciprint.h"
35 #include "Scierror.h"
36
37 #include "MALLOC.h"             /* MALLOC */
38 #include "scitokenize.h"
39 #include "localization.h"
40 #include "get_ticks_utils.h"
41 #include "HandleManagement.h"
42 #include "freeArrayOfString.h"
43
44 #include "getGraphicObjectProperty.h"
45 #include "setGraphicObjectProperty.h"
46 #include "graphicObjectProperties.h"
47 #include "CurrentFigure.h"
48 #include "CurrentSubwin.h"
49 #include "CurrentObject.h"
50
51 /*--------------------------------------------------------------------
52  *  plot2dn(ptype,Logflags,x,y,n1,n2,style,strflag,legend,brect,aaint,lstr1,lstr2)
53  *
54  *  Draw *n1 curves of *n2 points each
55  *
56  *  ptype is an int which gives the polyline drawind mode (0,1,2,3,4)
57  *
58  *  Logflags is a two character string
59  *
60  *  (x[i+(*n2)*j] ,y[i+(*n2)*j]) Double values giving the point
61  *  position of point i of curve j (i=0,*n2-1 j=0,*n1-1)
62  *
63  *  style[*n1]-> give the style to use for each curve
64  *     if style is positive --> a mark is used (mark id = style[i])
65  *     if style is strictly negative --> a dashed line is used
66  *        (dash id = abs(style[i])
67  *     if there's only one curve, style can be of type style[0]=style,
68  *     style[1]=pos (pos in [1,6])
69  *     pos give the legend position (1 to 6) (this can be iteresting
70  *     if you want to superpose curves with different legends by
71  *     calling plot2d more than one time.
72  *
73  *  strflag[3] is a string
74  *
75  *     if strflag[0] == '1' then legends are added
76  *        legend = "leg1@leg2@....@legn"; gives the legend for each curve
77  *      else no legend
78  *
79  *     if strflag[1] == '1' then  the values of brect are used to fix
80  *        the drawing boundaries :  brect[]= <xmin,ymin,xmax,ymax>;
81  *      if strflag[1] == '2' then the values  are computed from data
82  *      else if strflag[1]=='0' the previous values
83  *                (previous call or defaut values) are used
84  *
85  *     if  strflag[2] == '1' ->then an axis is added
86  *        the number of intervals
87  *        is specified by the vector aaint[4] of integers
88  *         <aaint[0],aaint[1]> specifies the x-axis number of  points
89  *         <aaint[2],aaint[3]> same for y-axis
90  *     if  strflag[2] == '2' -> no axis, only a box around the curves
91  *     else no box and no axis
92
93  * lstr* : unused (but used by Fortran)
94  *--------------------------------------------------------------------------*/
95
96 int plot2dn(int ptype, char *logflags, double *x, double *y, int *n1, int *n2, int *style, char *strflag, char *legend, double *brect, int *aaint,
97             BOOL flagNax, int lstr1, int lstr2)
98 {
99     char *psubwinUID = NULL;
100     char *curFigureUID = NULL;
101     int closeflag = 0;
102     int jj = 0;
103     long long *tabofhandles = NULL;
104     long hdl = 0;
105     long *hdltab = NULL;
106     int cmpt = 0;
107     int with_leg = 0;
108     double drect[6];
109     char dataflag = 0;
110
111     BOOL bounds_changed = FALSE;
112     BOOL axes_properties_changed = FALSE;
113
114     double rotationAngles[2];
115     int clipState = 0;
116     int autoScale = 0;
117     int logFlags[3];
118     int iTmp = 0;
119     int *piTmp = &iTmp;
120     char textLogFlags[3];
121     int firstPlot = 0;
122     int newFirstPlot = 0;
123     int autoSubticks = 0;
124
125     psubwinUID = (char*)getOrCreateDefaultSubwin();
126
127     /*
128      * Check if the auto_clear property is on and then erase everything
129      * To be implemented
130      */
131     checkRedrawing();
132
133     rotationAngles[0] = 0.0;
134     rotationAngles[1] = 270.0;
135
136     setGraphicObjectProperty(psubwinUID, __GO_ROTATION_ANGLES__, rotationAngles, jni_double_vector, 2);
137
138     /* Force logflags to those given by argument */
139
140     getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
141     firstPlot = iTmp;
142
143     /* Reset x and y logflags */
144     if (firstPlot)
145     {
146         logFlags[0] = getBooleanLogFlag(logflags[1]);
147         logFlags[1] = getBooleanLogFlag(logflags[2]);
148
149         setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, &logFlags[0], jni_bool, 1);
150         setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, &logFlags[1], jni_bool, 1);
151     }
152
153     /* Forces "clipgrf" clipping (1) */
154     clipState = 1;
155     setGraphicObjectProperty(psubwinUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
156
157     getGraphicObjectProperty(psubwinUID, __GO_AUTO_SCALE__, jni_bool, (void **)&piTmp);
158     autoScale = iTmp;
159
160     if (autoScale)
161     {
162         /* compute and merge new specified bounds with the data bounds */
163         switch (strflag[1])
164         {
165             case '0':
166                 /* do not change data bounds */
167                 break;
168             case '1':
169             case '3':
170             case '5':
171             case '7':
172                 /* Force data bounds=brect */
173                 re_index_brect(brect, drect);
174                 break;
175             case '2':
176             case '4':
177             case '6':
178             case '8':
179             case '9':
180                 /* Force data bounds to the x and y bounds */
181                 if ((int)strlen(logflags) < 1)
182                 {
183                     dataflag = 'g';
184                 }
185                 else
186                 {
187                     dataflag = logflags[0];
188                 }
189
190                 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
191                 logFlags[0] = iTmp;
192                 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
193                 logFlags[1] = iTmp;
194                 getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
195                 logFlags[2] = iTmp;
196
197                 /* Conversion required by compute_data_bounds2 */
198                 textLogFlags[0] = getTextLogFlag(logFlags[0]);
199                 textLogFlags[1] = getTextLogFlag(logFlags[1]);
200                 textLogFlags[2] = getTextLogFlag(logFlags[2]);
201
202                 compute_data_bounds2(0, dataflag, textLogFlags, x, y, *n1, *n2, drect);
203
204                 break;
205         }
206
207         /* merge data bounds and drect */
208         if (!firstPlot && (strflag[1] == '5' || strflag[1] == '7' || strflag[1] == '8' || strflag[1] == '9'))
209         {
210             double *dataBounds;
211
212             getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
213
214             drect[0] = Min(dataBounds[0], drect[0]);    /*xmin */
215             drect[2] = Min(dataBounds[2], drect[2]);    /*ymin */
216             drect[1] = Max(dataBounds[1], drect[1]);    /*xmax */
217             drect[3] = Max(dataBounds[3], drect[3]);    /*ymax */
218         }
219
220         if (strflag[1] != '0')
221         {
222             bounds_changed = update_specification_bounds(psubwinUID, drect, 2);
223         }
224     }
225
226     if (firstPlot)
227     {
228         bounds_changed = TRUE;
229     }
230
231     /* Adapted to the MVC */
232     axes_properties_changed = strflag2axes_properties(psubwinUID, strflag);
233
234     /* just after strflag2axes_properties */
235     newFirstPlot = 0;
236     setGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, &newFirstPlot, jni_bool, 1);
237
238     with_leg = (strflag[0] == '1');
239
240     /* F.Leray 07.10.04 : trigger algo to init. manual graduation u_xgrads and
241      * u_ygrads if nax (in matdes.c which is == aaint HERE) was specified */
242
243     /* The MVC AUTO_SUBTICKS property corresponds to !flagNax */
244     autoSubticks = !flagNax;
245     setGraphicObjectProperty(psubwinUID, __GO_AUTO_SUBTICKS__, &autoSubticks, jni_bool, 1);
246
247     if (flagNax == TRUE)
248     {
249         getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
250         logFlags[0] = iTmp;
251         getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
252         logFlags[1] = iTmp;
253
254         if (logFlags[0] == 0 && logFlags[1] == 0)
255         {
256             int autoTicks = 0;
257             int i = 0;
258             int iSize = 0;
259             double dblFabs = 0;
260             double* dXGrads = (double*) malloc(aaint[1] * sizeof(double));
261             double* dYGrads = (double*) malloc(aaint[3] * sizeof(double));
262             char** stringVector = NULL;
263
264             // set auto ticks to off
265             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
266             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
267
268             // Compute X grads
269             dXGrads[0] = drect[0];
270             if (aaint[1] > 1)
271             {
272                 double pas = (drect[1] - drect[0]) / (aaint[1] - 1);
273                 for (i = 0; i < aaint[1]; i++)
274                 {
275                     dXGrads[i] = drect[0] + pas * i;
276                 }
277             }
278
279             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LOCATIONS__, dXGrads, jni_double_vector, aaint[1]);
280
281             // Compute Y grads
282             dYGrads[0] = drect[2];
283             if (aaint[3] > 1)
284             {
285                 double pas = (drect[3] - drect[2]) / (aaint[3] - 1);
286                 for (i = 0; i < aaint[3]; i++)
287                 {
288                     dYGrads[i] = drect[2] + pas * i;
289                 }
290             }
291
292             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LOCATIONS__, dYGrads, jni_double_vector, aaint[3]);
293
294             // Create X Labels
295             stringVector = (char **) malloc(aaint[1] * sizeof(char*));
296             for (i = 0; i < aaint[1]; i++)
297             {
298                 iSize = 6;
299                 if (dXGrads[i] < 0)
300                 {
301                     iSize += 2;
302                 }
303                 dblFabs = fabs(dXGrads[i]);
304                 if (dblFabs >= 10)
305                 {
306                     iSize = iSize + (int)floor(log10(dblFabs));
307                 }
308
309                 stringVector[i] = (char*) malloc(iSize * sizeof(char));
310                 sprintf(stringVector[i], "%.3f", dXGrads[i]);
311                 stringVector[i][iSize - 1] = '\0';
312             }
313
314             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[1]);
315
316             for (i = 0; i < aaint[1]; i++)
317             {
318                 free(stringVector[i]);
319             }
320
321             free(stringVector);
322             stringVector = NULL;
323
324             // Create Y Labels
325             stringVector = (char**) malloc(aaint[3] * sizeof(char*));
326             for (i = 0; i < aaint[3]; i++)
327             {
328                 iSize = 6;
329                 if (dYGrads[i] < 0)
330                 {
331                     iSize += 2;
332                 }
333                 dblFabs = fabs(dYGrads[i]);
334                 if (dblFabs >= 10)
335                 {
336                     iSize = iSize + (int)floor(log10(dblFabs));
337                 }
338                 stringVector[i] = (char*) malloc(iSize * sizeof(char));
339                 sprintf(stringVector[i], "%.3f", dYGrads[i]);
340                 stringVector[i][iSize - 1] = '\0';
341             }
342
343             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[3]);
344
345             for (i = 0; i < aaint[3]; i++)
346             {
347                 free(stringVector[i]);
348             }
349
350             free(stringVector);
351             free(dXGrads);
352             free(dYGrads);
353
354             // X and Y subticks
355             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_SUBTICKS__, aaint, jni_int, 1);
356             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_SUBTICKS__, &aaint[2], jni_int, 1);
357
358         }
359         else
360         {
361             sciprint(_("Warning: Nax does not work with logarithmic scaling.\n"));
362         }
363
364     }
365
366     /*---- Drawing the curves and the legends ----*/
367     if (*n1 != 0)
368     {
369         if ((hdltab = MALLOC((*n1 + 1) * sizeof(long))) == NULL)
370         {
371             Scierror(999, _("%s: No more memory.\n"), "plot2d");
372             return -1;
373         }
374         if (with_leg)
375         {
376             /* tabofhandles allocated for legends */
377             if ((tabofhandles = MALLOC((*n1) * sizeof(long long))) == NULL)
378             {
379                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
380                 FREE(hdltab);
381                 return -1;
382             }
383         }
384
385         /*A.Djalel 3D axes */
386         for (jj = 0; jj < *n1; jj++)
387         {
388             char *pobjUID = NULL;
389
390             if (style[jj] > 0)
391             {
392                 BOOL isline = TRUE;
393
394                 if (ptype == 3)
395                 {
396                     isline = FALSE;
397                 }
398                 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
399                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
400                                             &style[jj], NULL, NULL, NULL, NULL, isline, FALSE, FALSE, FALSE);
401             }
402             else
403             {
404                 int minusstyle = -style[jj];
405
406                 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
407                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
408                                             NULL, NULL, &minusstyle, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
409             }
410             if (pobjUID == NULL)
411             {
412                 // skip
413                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
414             }
415             else
416             {
417                 setCurrentObject(pobjUID);
418
419                 hdl = getHandle(pobjUID);
420                 releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
421                 pobjUID = NULL;
422                 if (with_leg)
423                 {
424                     tabofhandles[cmpt] = hdl;
425                 }
426
427                 hdltab[cmpt] = hdl;
428                 cmpt++;
429             }
430
431         }
432
433         /*---- Drawing the Legends ----*/
434         if (with_leg)
435         {
436             char *legUID;
437             char **Str;
438             int nleg;
439
440             if (scitokenize(legend, &Str, &nleg))
441             {
442                 FREE(tabofhandles);
443                 FREE(hdltab);
444                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
445                 return 0;
446             }
447
448             legUID = ConstructLegend((char*)getCurrentSubWin(), Str, tabofhandles, Min(nleg, cmpt));
449
450             if (legUID != NULL)
451             {
452                 int legendLocation;
453                 int contourMode;
454
455                 /* 9: LOWER_CAPTION */
456                 legendLocation = 9;
457                 setGraphicObjectProperty(legUID, __GO_LEGEND_LOCATION__, &legendLocation, jni_int, 1);
458
459                 contourMode = 0;
460
461                 setGraphicObjectProperty(legUID, __GO_FILL_MODE__, &contourMode, jni_bool, 1);
462                 setGraphicObjectProperty(legUID, __GO_LINE_MODE__, &contourMode, jni_bool, 1);
463             }
464
465             freeArrayOfString(Str, nleg);
466
467             FREE(tabofhandles);
468         }
469
470         /*---- construct Compound ----*/
471         if (cmpt > 0)
472         {
473             int parentVisible = 0;
474             int *piParentVisible = &parentVisible;
475             char* compoundUID = ConstructCompound (hdltab, cmpt);
476             setCurrentObject(compoundUID);
477             setGraphicObjectRelationship(psubwinUID, compoundUID);
478             getGraphicObjectProperty(psubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
479             setGraphicObjectProperty(compoundUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
480             releaseGraphicObjectProperty(__GO_PARENT__, compoundUID, jni_string, 1);
481         }
482         FREE(hdltab);
483
484     }
485     /* End of the curves and legend block */
486
487     return (0);
488 }
489
490 /* Given two set of coordinates x and y this routine computes the corresponding
491  *  data bounds rectangle drect=[xmin,ymin,xmax,ymax] taking into account the logflag
492  *  -> means we have to find among the data the min > 0.
493  */
494 void compute_data_bounds2(int cflag, char dataflag, char *logflags, double *x, double *y, int n1, int n2, double *drect)
495 {
496     int size_x = 0, size_y = 0;
497     double xd[2];
498     double *x1 = NULL;
499
500     switch (dataflag)
501     {
502         case 'e':
503             xd[0] = 1.0;
504             xd[1] = (double)n2;
505             x1 = xd;
506             size_x = (n2 != 0) ? 2 : 0;
507             break;
508         case 'o':
509             x1 = x;
510             size_x = n2;
511             break;
512         case 'g':
513         default:
514             x1 = x;
515             size_x = (cflag == 1) ? n1 : (n1 * n2);
516             break;
517     }
518
519     if (size_x != 0)
520     {
521         if (logflags[0] != 'l')
522         {
523             MiniMaxi(x1, size_x, drect, drect + 1);
524             //drect[0] = Mini(x1, size_x);
525             //drect[1] = Maxi(x1, size_x);
526         }
527         else
528         {
529             /* log. case */
530             drect[0] = sciFindStPosMin(x1, size_x);
531             drect[1] = Maxi(x1, size_x);
532         }
533
534     }
535     else
536     {
537         if (logflags[0] != 'l')
538         {
539             drect[0] = 0.0;
540             drect[1] = 10.0;
541         }
542         else
543         {
544             /* log. case */
545             drect[0] = 1.0;
546             drect[1] = 10.0;
547         }
548     }
549
550     size_y = (cflag == 1) ? n2 : (n1 * n2);
551     if (size_y != 0)
552     {
553         if (logflags[1] != 'l')
554         {
555             MiniMaxi(y, size_y, drect + 2, drect + 3);
556             //drect[2] = Mini(y, size_y);
557             //drect[3] = Maxi(y, size_y);
558         }
559         else
560         {
561             /* log. case */
562             drect[2] = sciFindStPosMin(y, size_y);
563             drect[3] = Maxi(y, size_y);
564         }
565     }
566     else
567     {
568         if (logflags[1] != 'l')
569         {
570             drect[2] = 0.0;
571             drect[3] = 10.0;
572         }
573         else
574         {
575             /* log. case */
576             drect[2] = 1.0;
577             drect[3] = 10.0;
578         }
579     }
580
581     /* back to default values for  x=[] and y = [] */
582     if (drect[2] == LARGEST_REAL || drect[3] == -LARGEST_REAL)
583     {
584         if (logflags[1] != 'l')
585         {
586             drect[2] = 0.0;
587         }
588         else
589         {
590             drect[2] = 1.0;
591         }
592
593         drect[3] = 10.0;
594     }
595
596     if (drect[0] == LARGEST_REAL || drect[1] == -LARGEST_REAL)
597     {
598         if (logflags[0] != 'l')
599         {
600             drect[0] = 0.0;
601         }
602         else
603         {
604             drect[0] = 1.0;
605         }
606
607         drect[1] = 10.0;
608     }
609 }
610
611 BOOL update_specification_bounds(char *psubwinUID, double rect[6], int flag)
612 {
613     double *dataBounds = NULL;
614
615     /*
616      * 2D: keep the existing zmin and zmax
617      * which is why they must be fetched
618      */
619     if (flag != 3)
620     {
621         getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
622
623         rect[4] = dataBounds[4];
624         rect[5] = dataBounds[5];
625     }
626
627     setGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
628
629     return TRUE;
630 }
631
632 /* F.Leray */
633 /* brect must have the same format as drect i.e.: [xmin,xmax,ymin,ymax] */
634 /* brect = INPUT ; drect = OUTPUT (warning drect is dim 6) */
635 int re_index_brect(double *brect, double *drect)
636 {
637     drect[0] = brect[0];
638     drect[1] = brect[2];
639     drect[2] = brect[1];
640     drect[3] = brect[3];
641
642     return 0;
643 }
644
645 /* F.Leray 07.05.04 */
646 /* Dispatch info contained in strflag to all the flag available in
647    sciSubwin object (tight_limits, isoview, isaxes...) */
648 /*
649  * This function has been adapted to the MVC framework
650  */
651 BOOL strflag2axes_properties(char *psubwinUID, char *strflag)
652 {
653     BOOL haschanged = FALSE;
654     BOOL tightLimitsPrev = FALSE;
655     BOOL isoviewPrev = FALSE;
656     int boxPrev = 0;
657     int tightLimits = 0;
658     int firstPlot = 0;
659     int axisVisible = 0;
660     int boxType = 0;
661     int xLocationPrev = 0;
662     int yLocationPrev = 0;
663     int xLocation = 0;
664     int yLocation = 0;
665     int isoview = 0;
666     int axesVisiblePrev[3];
667     int axesVisible[3];
668
669     int iTmp = 0;
670     int *piTmp = &iTmp;
671
672     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
673     axesVisiblePrev[0] = iTmp;
674     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
675     axesVisiblePrev[1] = iTmp;
676     getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
677     axesVisiblePrev[2] = iTmp;
678
679     getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
680     boxPrev = iTmp;
681
682     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
683     xLocationPrev = iTmp;
684     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
685     yLocationPrev = iTmp;
686
687     getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
688     tightLimitsPrev = iTmp;
689     getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
690     isoviewPrev = iTmp;
691
692     /* F.Leray 07.05.04 */
693     /* strflag[1] Isoview & tight_limits flags management */
694     switch (strflag[1])
695     {
696         case '0':
697         case '9':
698             /* no changes */
699             break;
700         case '1':
701         case '2':
702         case '7':
703         case '8':
704             tightLimits = 1;
705             setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
706             break;
707         case '3':
708         case '4':
709             isoview = 1;
710             setGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, &isoview, jni_bool, 1);
711             break;
712         case '5':
713         case '6':
714             /* pretty axes */
715             tightLimits = 0;
716             setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
717             break;
718     }
719
720     /* F.Leray 07.05.04 */
721     /* strflag[2] */
722     switch (strflag[2])
723     {
724
725         case '0':
726             getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
727             firstPlot = iTmp;
728
729             if (firstPlot)
730             {
731                 axisVisible = 0;
732                 /* 0: OFF */
733                 boxType = 0;
734
735                 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
736                 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
737                 /* also trigger z axis */
738                 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
739                 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
740             }
741             /*else no changes : the isaxes properties is driven by the previous plot */
742             break;
743         case '1':
744             axisVisible = 1;
745             /* 1: ON */
746             boxType = 1;
747             /* 4: LEFT */
748             yLocation = 4;
749
750             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
751             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
752             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
753             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
754             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
755
756             break;
757         case '2':
758             axisVisible = 0;
759             boxType = 1;
760
761             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
762             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
763             /* also trigger z axis */
764             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
765             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
766
767             break;
768         case '3':
769             axisVisible = 1;
770             boxType = 0;
771             /* 5: RIGHT */
772             yLocation = 5;
773
774             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
775             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
776             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
777             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
778             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
779
780             break;
781         case '4':
782             axisVisible = 1;
783             /* 2: MIDDLE */
784             xLocation = 2;
785             yLocation = 2;
786             boxType = 0;
787
788             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
789             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
790             /* also trigger z axis */
791             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
792             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
793             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
794             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
795
796             break;
797         case '5':
798             axisVisible = 1;
799             xLocation = 2;
800             yLocation = 2;
801             boxType = 1;
802
803             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
804             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
805             /* also trigger z axis */
806             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
807             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
808             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
809             setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
810
811             break;
812         case '9':
813             axisVisible = 1;
814
815             setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
816             setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
817             /* also trigger z axis */
818             setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
819     }
820
821     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
822     axesVisible[0] = iTmp;
823     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
824     axesVisible[1] = iTmp;
825     getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
826     axesVisible[2] = iTmp;
827
828     getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
829     boxType = iTmp;
830
831     getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
832     xLocation = iTmp;
833     getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
834     yLocation = iTmp;
835
836     getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
837     tightLimits = iTmp;
838     getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
839     isoview = iTmp;
840
841     /* Find if something has changed */
842     if (axesVisible[0] != axesVisiblePrev[0]
843             || axesVisible[1] != axesVisiblePrev[1]
844             || axesVisible[2] != axesVisiblePrev[2]
845             || xLocation != xLocationPrev || yLocation != yLocationPrev || boxType != boxPrev || tightLimits != tightLimitsPrev || isoview != isoviewPrev)
846     {
847         haschanged = TRUE;
848     }
849     else
850     {
851         haschanged = FALSE;
852     }
853
854     return haschanged;
855 }