a22fd7b3335a5c149b8347d9bc01eaa52e61ff9e
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_set.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Allan Cornet
4  * Copyright (C) 2006 - INRIA - Fabrice Leray
5  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
6  * Copyright (C) 2006 - INRIA - Vincent Couvert
7  * Copyright (C) 2011 - DIGITEO - Allan CORNET
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.1-en.txt
14  *
15  */
16
17 /*------------------------------------------------------------------------*/
18 /* file: sci_set.h                                                        */
19 /* desc : interface for sci_set routine                                   */
20 /*------------------------------------------------------------------------*/
21 #include <stdio.h>
22 /*------------------------------------------------------------------------*/
23 #include "gw_graphics.h"
24 #include "stack-c.h"
25 #include "Scierror.h"
26 #include "HandleManagement.h"
27 #include "GetProperty.h"
28 #include "InitObjects.h"
29 #include "freeArrayOfString.h"
30
31 #include "SetHashTable.h"
32 #include "SetPropertyStatus.h"
33
34 #include "MALLOC.h"             /* MALLOC */
35 #include "localization.h"
36 #include "stricmp.h"
37 #include "api_scilab.h"
38 #include "FigureList.h"
39
40 /*--------------------------------------------------------------------------
41  * sciset(choice-name,x1,x2,x3,x4,x5)
42  * or   xset()
43  *-----------------------------------------------------------*/
44 int sci_set(char *fname, unsigned long fname_len)
45 {
46     SciErr sciErr;
47     int i = 0;
48     int* piAddr1 = NULL;
49
50     int isMatrixOfString = 0;
51
52     char* pstProperty = NULL;
53     char* pstNewProperty = NULL;
54
55     unsigned long hdl;
56     int iObjUID = 0;
57     int iType = 0;
58     int* piType = &iType;
59
60     int iSetProperty = 0;
61
62     int iRhs = nbInputArgument(pvApiCtx);
63     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
64     if (sciErr.iErr)
65     {
66         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
67         return 1;
68     }
69
70     if (isMListType(pvApiCtx, piAddr1) || isTListType(pvApiCtx, piAddr1))
71     {
72         OverLoad(1);
73         return 0;
74     }
75
76     CheckInputArgumentAtLeast(pvApiCtx, 2);
77     CheckOutputArgument(pvApiCtx, 0, 1);
78
79     if (isDoubleType(pvApiCtx, piAddr1))   /* tclsci handle */
80     {
81         /* call "set" for tcl/tk see tclsci/sci_gateway/c/sci_set.c */
82         OverLoad(1);
83         return 0;
84     }
85
86     if (iRhs == 2)
87     {
88 #define NB_PROPERTIES_SUPPORTED 7
89         /* No object specified */
90         /* ONLY supported properties are */
91         /* 'current_entity' */
92         /* 'hdl' */
93         /* 'current_figure' */
94         /* 'current_axes' */
95         /* 'default_values' */
96         /* 'figure_style' for compatibility but do nothing */
97         /* others values must return a error */
98         char *propertiesSupported[NB_PROPERTIES_SUPPORTED] =
99         {
100             "current_entity",
101             "hdl",
102             "current_figure",
103             "current_axes",
104             "figure_style",
105             "default_values",
106             "auto_clear"
107         };
108
109         int iPropertyFound = 0;
110         int* piAddr2 = NULL;
111         int iType2 = 0;
112         int iRows2 = 0;
113         int iCols2 = 0;
114         void* pvData = NULL;
115
116         if (isStringType(pvApiCtx, piAddr1) == 0)
117         {
118             Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
119             return 0;
120         }
121
122         if (getAllocatedSingleString(pvApiCtx, piAddr1, &pstProperty))
123         {
124             Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
125             return 1;
126         }
127
128         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
129         if (sciErr.iErr)
130         {
131             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
132             return 1;
133         }
134
135         sciErr = getVarType(pvApiCtx, piAddr2, &iType2);
136         if (sciErr.iErr)
137         {
138             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
139             return 1;
140         }
141
142         switch (iType2)
143         {
144             case sci_matrix:
145                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &iRows2, &iCols2, (double**)&pvData);
146                 if (sciErr.iErr)
147                 {
148                     printError(&sciErr, 0);
149                     Scierror(999, _("%s: Wrong type for input argument #%d: Matrix expected.\n"), fname, 2);
150                     return sciErr.iErr;
151                 }
152                 break;
153             case sci_handles :
154                 sciErr = getMatrixOfHandle(pvApiCtx, piAddr2, &iRows2, &iCols2, (long long**)&pvData);
155                 if (sciErr.iErr)
156                 {
157                     printError(&sciErr, 0);
158                     Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of handle expected.\n"), fname, 3);
159                     return 1;
160                 }
161                 break;
162             case sci_strings :
163                 if (strcmp(pstProperty, "tics_labels") == 0 || strcmp(pstProperty, "auto_ticks") == 0 ||
164                         strcmp(pstProperty, "axes_visible") == 0 || strcmp(pstProperty, "axes_reverse") == 0 ||
165                         strcmp(pstProperty, "text") == 0)
166                 {
167                     isMatrixOfString = 1;
168                     if (getAllocatedMatrixOfString(pvApiCtx, piAddr2, &iRows2, &iCols2, (char***)&pvData))
169                     {
170                         Scierror(999, _("%s: Wrong size for input argument #%d: A matrix of string expected.\n"), fname, 2);
171                         return 1;
172                     }
173                 }
174                 else
175                 {
176                     if (getAllocatedSingleString(pvApiCtx, piAddr2, (char**)&pvData))
177                     {
178                         Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 2);
179                         return 1;
180                     }
181                     iRows2 = (int)strlen((char*)pvData);
182                     iCols2 = 1;
183                     isMatrixOfString = 0;
184                 }
185                 break;
186         }
187
188
189
190         for (i = 0; i < NB_PROPERTIES_SUPPORTED; i++)
191         {
192
193             if (strcmp(propertiesSupported[i], pstProperty) == 0)
194             {
195                 iPropertyFound = 1;
196             }
197         }
198
199         if (iPropertyFound)
200         {
201             callSetProperty(pvApiCtx, NULL, pvData, iType2, iRows2, iCols2, pstProperty);
202             if (iType2 == sci_strings)
203             {
204                 //free allocated data
205                 if (isMatrixOfString == 1)
206                 {
207                     freeAllocatedMatrixOfString(iRows2, iCols2, (char**)pvData);
208                 }
209                 else
210                 {
211                     freeAllocatedSingleString((char*)pvData);
212                 }
213             }
214         }
215         else
216         {
217             Scierror(999, _("%s: Wrong value for input argument #%d: a valid property expected.\n"), fname, 1);
218             if (iType2 == sci_strings)
219             {
220                 if (isMatrixOfString == 1)
221                 {
222                     freeAllocatedMatrixOfString(iRows2, iCols2, (char**)pvData);
223                 }
224                 else
225                 {
226                     freeAllocatedSingleString((char*)pvData);
227                 }
228             }
229             return 0;
230         }
231
232         AssignOutputVariable(pvApiCtx, 1) = 0;
233         ReturnArguments(pvApiCtx);
234         return 0;
235     }
236
237     if (iRhs % 2 != 1)
238     {
239         Scierror(999, _("%s: Wrong number of input argument(s) : an odd number is expected.\n"), fname);
240         return 0;
241     }
242
243
244     /* after the call to sciSet get the status : 0 <=> OK,          */
245     /*                                          -1 <=> Error,       */
246     /*                                           1 <=> nothing done */
247
248     /*  set or create a graphic window */
249     if (isHandleType(pvApiCtx, piAddr1) == 0 && isStringType(pvApiCtx, piAddr1) == 0)
250     {
251         Scierror(999, _("%s: Wrong type for input argument #%d: A handle or a string expected.\n"), fname, 1);
252         return 0;
253     }
254
255     if (isStringType(pvApiCtx, piAddr1))
256     {
257         char* pstPath = NULL;
258         if (getAllocatedSingleString(pvApiCtx, piAddr1, &pstPath))
259         {
260             Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 1);
261             return 1;
262         }
263
264         iObjUID = search_path(pstPath);
265         if (iObjUID == 0)
266         {
267             Scierror(999, _("%s: Unable to find handle for path %s.\n"), fname, pstPath);
268             freeAllocatedSingleString(pstPath);
269             return 1;
270         }
271     }
272     else
273     {
274         //matrix of handle are managed by a %h_set
275         if (isScalar(pvApiCtx, piAddr1) == FALSE)
276         {
277             OverLoad(1);
278             return 0;
279         }
280
281         if (getScalarHandle(pvApiCtx, piAddr1, (long long*)&hdl))
282         {
283             Scierror(999, _("%s: Wrong size for input argument #%d: A single handle expected.\n"), fname, 1);
284             return 1;
285         }
286
287         iObjUID = getObjectFromHandle(hdl);
288     }
289
290     if (iObjUID == 0)
291     {
292         Scierror(999, _("%s: The handle is not or no more valid.\n"), fname);
293         return 0;
294     }
295
296     for (i = 1 ; i < iRhs ; i = i + 2)
297     {
298         int setStatus = 0;
299         int* piAddr2 = NULL;
300         int* piAddr3 = NULL;
301
302         int iPos = i + 1;
303         int isData = 0;
304
305         int iRows3 = 0;
306         int iCols3 = 0;
307         int iType3 = 0;
308         void* pvData = NULL;
309
310         sciErr = getVarAddressFromPosition(pvApiCtx, iPos, &piAddr2);
311         if (sciErr.iErr)
312         {
313             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos);
314             return 1;
315         }
316
317         if (isStringType(pvApiCtx, piAddr2) == 0)
318         {
319             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, iPos);
320             return 0;
321         }
322
323         if (getAllocatedSingleString(pvApiCtx, piAddr2, &pstProperty))
324         {
325             Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, iPos);
326             return 1;
327         }
328
329         sciErr = getVarAddressFromPosition(pvApiCtx, iPos + 1, &piAddr3);
330         if (sciErr.iErr)
331         {
332             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
333             return 1;
334         }
335
336         if ((pstProperty[0] == 'd' || pstProperty[0] == 'D') && stricmp("data", pstProperty) == 0)
337         {
338             //send to datamodel
339             isData = 1;
340         }
341
342         if ((strcmp(pstProperty, "user_data") == 0) || (stricmp(pstProperty, "userdata") == 0))
343         {
344             /* in this case set_user_data_property
345             * directly uses the  third position in the stack
346             * to get the variable which is to be set in
347             * the user_data property (any data type is allowed) S. Steer */
348             pvData = (void*)piAddr3;         /*position in the stack */
349             iRows3 = -1;   /*unused */
350             iCols3 = -1;   /*unused */
351             iType3 = -1;
352         }
353         else
354         {
355             sciErr = getVarType(pvApiCtx, piAddr3, &iType3);
356             if (sciErr.iErr)
357             {
358                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
359                 return 1;
360             }
361
362             switch (iType3)
363             {
364                 case sci_matrix :
365                     sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &iRows3, &iCols3, (double**)&pvData);
366                     break;
367                 case sci_boolean :
368                     sciErr = getMatrixOfBoolean(pvApiCtx, piAddr3, &iRows3, &iCols3, (int**)&pvData);
369                     break;
370                 case sci_handles :
371                     sciErr = getMatrixOfHandle(pvApiCtx, piAddr3, &iRows3, &iCols3, (long long**)&pvData);
372                     break;
373                 case sci_strings :
374                     if (strcmp(pstProperty, "tics_labels") != 0 && strcmp(pstProperty, "auto_ticks") != 0 &&
375                             strcmp(pstProperty, "axes_visible") != 0 && strcmp(pstProperty, "axes_reverse") != 0 &&
376                             strcmp(pstProperty, "text") != 0 && stricmp(pstProperty, "string") != 0 &&
377                             stricmp(pstProperty, "tooltipstring") != 0) /* Added for uicontrols */
378                     {
379                         if (isScalar(pvApiCtx, piAddr3) == 0)
380                         {
381                             Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, iPos + 1);
382                             return 1;
383                         }
384
385                         if (getAllocatedSingleString(pvApiCtx, piAddr3, (char**)&pvData))
386                         {
387                             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
388                             return 1;
389                         }
390                         iRows3 = (int)strlen((char*)pvData);
391                         iCols3 = 1;
392                         isMatrixOfString = 0;
393                     }
394                     else
395                     {
396                         isMatrixOfString = 1;
397                         getAllocatedMatrixOfString(pvApiCtx, piAddr3, &iRows3, &iCols3, (char***)&pvData);
398                     }
399                     break;
400                 case sci_list :
401                     iCols3 = 1;
402                     sciErr = getListItemNumber(pvApiCtx, piAddr3, &iRows3);
403                     pvData = (void*)piAddr3;         /* In this case l3 is the list position in stack */
404                     break;
405                 default :
406                     pvData = (void*)piAddr3;         /* In this case l3 is the list position in stack */
407                     break;
408             }
409
410             if (sciErr.iErr)
411             {
412                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, iPos + 1);
413                 return 1;
414             }
415         }
416
417         setStatus = callSetProperty(pvApiCtx, iObjUID, pvData, iType3, iRows3, iCols3, pstProperty);
418         if (iType3 == sci_strings)
419         {
420             //free allacted data
421             if (isMatrixOfString == 1)
422             {
423                 freeAllocatedMatrixOfString(iRows3, iCols3, (char**)pvData);
424             }
425             else
426             {
427                 freeAllocatedSingleString((char*)pvData);
428             }
429         }
430     }
431
432     freeAllocatedSingleString(pstProperty);
433
434     AssignOutputVariable(pvApiCtx, 1) = 0;
435     ReturnArguments(pvApiCtx);
436     return 0;
437 }
438 /*--------------------------------------------------------------------------*/