Fix crash on Scicos exiting when simulation was stoped and some scope closed
[scilab.git] / scilab / modules / scicos_blocks / src / c / canimxy.c
1 /*  Scicos
2  *
3  *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  * See the file ./license.txt
20  */
21 /**
22    \file canimxy.c
23    \author Benoit Bayol
24    \version 1.0
25    \date September 2006 - January 2007
26    \brief CANIMXY is a scope in 2D which draw its input as a XY scope, there is animation.
27    \see CANIMXY.sci in macros/scicos_blocks/Sinks/
28 */
29 #include "CurrentObjectsManagement.h"
30 #include "scoMemoryScope.h"
31 #include "scoWindowScope.h"
32 #include "scoMisc.h"
33 #include "scoGetProperty.h"
34 #include "scoSetProperty.h"
35 #include "scicos_block4.h"
36 #include "DrawingBridge.h"
37
38 /** \fn canimxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
39     \brief Function to draw or redraw the window
40 */
41 void canimxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
42 {
43   /* Declarations*/
44   int i;
45   int gomme_color; //As usual
46   int * ipar; //Integer Parameters
47   int color_flag; //Flag on Color
48   int color[2];
49   int line_size;
50   int animed;
51   int win; //Windows ID : To give a name to the window
52   int buffer_size; //Buffer Size
53   int win_pos[2]; //Position of the Window
54   int win_dim[2]; //Dimension of the Window
55   int nipar;
56   double * rpar; //Reals parameters
57   double xmin, xmax, ymin, ymax; //Ymin and Ymax are vectors here
58   scoGraphicalObject Pinceau; //Pointer to each polyline of each axes
59   scoGraphicalObject Gomme; //Pointer to each polyline of each axes
60   scoGraphicalObject Trait; //Pointer to each trache of each axes
61   int number_of_subwin;
62   int number_of_curves_by_subwin;
63   int dimension = 2;
64   int nbr_curves;
65
66   ipar = GetIparPtrs(block);
67   nipar = GetNipar(block);
68   rpar = GetRparPtrs(block);
69   win = ipar[0];
70   color_flag = ipar[1];
71   buffer_size = ipar[2];
72   color[0] = ipar[3];
73   color[1] = ipar[3];
74   line_size = ipar[4];
75   animed = ipar[5];
76   win_pos[0] = ipar[6];
77   win_pos[1] = ipar[7];
78   win_dim[0] = ipar[8];
79   win_dim[1] = ipar[9];
80   nbr_curves = ipar[10];
81   xmin = rpar[0];
82   xmax = rpar[1];
83   ymin = rpar[2];
84   ymax = rpar[3]; 
85   number_of_subwin = 1;
86
87   /* If only one element to draw*/
88   if (buffer_size == 1)
89     {
90       number_of_curves_by_subwin = nbr_curves;
91       if(firstdraw == 1)
92         {
93           scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
94           scoSetShortDrawSize(*pScopeMemory,0,1);
95           scoSetLongDrawSize(*pScopeMemory,0,0);
96         }
97       scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
98       if(scoGetScopeActivation(*pScopeMemory) == 1)
99         {
100
101           sciSetPixmapMode(scoGetPointerScopeWindow(*pScopeMemory),TRUE);
102           pFIGURE_FEATURE(scoGetPointerScopeWindow(*pScopeMemory))->pixmapMode = 1;
103
104
105           for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(*pScopeMemory, 0) ; i++)
106             {
107               scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
108               Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
109               pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
110               sciSetMarkSize(Pinceau, line_size);
111
112             }
113         }
114     }
115   /*else if 2 or more elements*/
116   else
117     {
118       number_of_curves_by_subwin = 2*nbr_curves; //it is a trick to recognize the type of scope, not sure it is a good way because normally a curve is the combination of a short and a longdraw
119       if(firstdraw == 1)
120         {
121           scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
122         }
123
124       scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
125       if(scoGetScopeActivation(*pScopeMemory) == 1)
126         {
127           gomme_color = sciGetBackground(scoGetPointerAxes(*pScopeMemory,0));
128           //sciSetIsBoxed(scoGetPointerAxes(*pScopeMemory,0),FALSE); //** obsolete in Scilab 5
129           /*if mark style*/
130           if(color[0] <= 0)
131             {
132               if(firstdraw == 1)
133                 {
134                   scoSetShortDrawSize(*pScopeMemory,0,1);
135                   scoSetLongDrawSize(*pScopeMemory,0,buffer_size-1);
136                 }
137               for(i = 0 ; i < nbr_curves ; i++)
138                 {
139                   //because of color[0] is negative it will add a black mark with style number color[0]
140                   scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
141                   scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,color[0]); //same type of mark and black for the rubber
142                   scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[0]);
143                     
144                   Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
145                   Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
146                   Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
147                     
148                   pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
149                   pPOLYLINE_FEATURE(Gomme)->n1 = 1;
150                   sciSetMarkForeground(Gomme, gomme_color); //here the rubber becomes colored like the background of the axes
151                   pPOLYLINE_FEATURE(Trait)->n1 = buffer_size-1;
152
153                   sciSetMarkSize(Pinceau, line_size);
154                   sciSetMarkSize(Gomme, line_size);
155                   sciSetMarkSize(Trait, line_size);
156                 }
157             }
158           /*if line style*/
159           else
160             {
161               if(firstdraw == 1)
162                 {
163                   scoSetShortDrawSize(*pScopeMemory,0,2);
164                   scoSetLongDrawSize(*pScopeMemory,0,buffer_size-1);
165                 }               
166               for(i = 0 ; i < nbr_curves ; i++)
167                 {
168                   scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
169                   scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,gomme_color);
170                   scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[0]);
171                     
172                   Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
173                   Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
174                   Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
175                     
176                   pPOLYLINE_FEATURE(Pinceau)->n1 = 2;
177                   pPOLYLINE_FEATURE(Gomme)->n1 = 2;
178                   pPOLYLINE_FEATURE(Trait)->n1 = buffer_size-1;
179
180                   sciSetLineWidth(Pinceau, line_size);
181                   sciSetLineWidth(Gomme, line_size);
182                   sciSetLineWidth(Trait, line_size);
183                 }
184             }
185         }
186     }
187   if(scoGetScopeActivation(*pScopeMemory) == 1)
188     {
189       scoAddTitlesScope(*pScopeMemory,"x","y",NULL);
190     }
191 }
192
193 /** \fn void canimxy(scicos_block * block, int flag)
194     \brief the computational function
195     \param block A pointer to a scicos_block
196     \param flag An int which indicates the state of the block (init, update, ending)
197 */
198 void canimxy(scicos_block * block, int flag)
199 {
200   /*Declarations*/
201   ScopeMemory * pScopeMemory;
202   double *u1,*u2;
203   scoGraphicalObject pShortDraw,pLongDraw;
204   int i;
205   /* State Machine Control */
206   switch(flag)
207     {
208     case Initialization:
209       { 
210         canimxy_draw(block,&pScopeMemory,1);
211         break; //Break of the switch condition don t forget it
212       } //End of Initialization
213
214     case StateUpdate:
215       {
216         scoRetrieveScopeMemory(block->work,&pScopeMemory);
217         if(scoGetScopeActivation(pScopeMemory) == 1)
218           {
219
220             /* Charging Elements */
221             if (scoGetPointerScopeWindow(pScopeMemory) == NULL) // If the window has been destroyed we recreate it
222               {
223                 canimxy_draw(block,&pScopeMemory,0);
224               }
225
226             /*Retrieve Elements*/
227             u1 = GetRealInPortPtrs(block,1);
228             u2 = GetRealInPortPtrs(block,2);
229
230             scoDrawScopeAnimXYStyle(pScopeMemory,u1,u2,NULL);
231           }
232         break; //Break of the switch don t forget it !
233       }//End of stateupdate
234       
235       //This case is activated when the simulation is done or when we close scicos
236     case Ending:
237       {
238                                 scoRetrieveScopeMemory(block->work, &pScopeMemory);
239                                 if(scoGetScopeActivation(pScopeMemory) == 1)
240                                 {
241                                         /* sciSetUsedWindow(scoGetWindowID(pScopeMemory)); */
242                                         /* Check if figure is still opened, otherwise, don't try to destroy it again. */
243                                         scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
244                                         if (figure != NULL)
245                                         {
246                                                 if(scoGetLongDrawSize(pScopeMemory,0) == 0)
247                                                 {
248                                                         for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
249                                                         {
250                                                                 pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
251                                                                 forceRedraw(pLongDraw);
252                                                         }
253                                                 }
254                                                 else
255                                                 {
256                                                         for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0)/2 ; i++)
257                                                         {
258                                                                 pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
259                                                                 forceRedraw(pLongDraw);
260                                                         }
261                                                 }
262                                         }
263                                         //Attention : here pShortDraw is a Window
264                                         /* pShortDraw = sciGetCurrentFigure(); */
265                                         /*pFIGURE_FEATURE(pShortDraw)->user_data = NULL;*/
266                                         /*pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;*/
267                                         clearUserData(figure);
268                                 }
269                                 scoFreeScopeMemory(block->work, &pScopeMemory);
270                                 break; //Break of the switch
271       }
272       //free the memory which is allocated at each turn by some variables
273  
274     }
275 }