1 /*****************************************************************
2  * gmerlin - a general purpose multimedia framework and applications
3  *
4  * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5  * gmerlin-general@lists.sourceforge.net
6  * http://gmerlin.sourceforge.net
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  * *****************************************************************/
21 
22 #ifndef __BG_PARAMETER_H_
23 #define __BG_PARAMETER_H_
24 
25 #include <libxml/tree.h>
26 #include <libxml/parser.h>
27 
28 #include <gavl/gavl.h>
29 
30 /**  \defgroup parameter Parameter description
31  *
32  *   Parameters are universal data containers, which
33  *   are the basis for all configuration mechanisms.
34  *
35  *   A configurable module foo, should provide at least 2 functions.
36  *   One, which lets the application get a null-terminated array of parameter description
37  *   and one of type \ref bg_set_parameter_func_t. It's up to the module, if the parameter array
38  *   is allocated per instance or if it's just a static array. Some parameters (e.g. window
39  *   coordinates) are not configured by a dialog. Instead, they are changed by the module.
40  *   For these parameters, set \ref BG_PARAMETER_HIDE_DIALOG for the flags and provide another
41  *   function of type \ref bg_get_parameter_func_t, which lets the core read the updated value.
42  */
43 
44 /* Universal Parameter setting mechanism */
45 
46 /** \ingroup parameter
47  *  \brief Parameter type
48  *
49  *  These define both the data type and
50  *  the appearance of an eventual configuration widget.
51  */
52 
53 typedef enum
54   {
55     BG_PARAMETER_SECTION, //!< Dummy type. It contains no data but acts as a separator in notebook style configuration windows
56     BG_PARAMETER_CHECKBUTTON, //!< Bool
57     BG_PARAMETER_INT,         //!< Integer spinbutton
58     BG_PARAMETER_FLOAT,       //!< Float spinbutton
59     BG_PARAMETER_SLIDER_INT,  //!< Integer slider
60     BG_PARAMETER_SLIDER_FLOAT, //!< Float slider
61     BG_PARAMETER_STRING,      //!< String (one line only)
62     BG_PARAMETER_STRING_HIDDEN, //!< Encrypted string (displays as ***)
63     BG_PARAMETER_STRINGLIST,  //!< Popdown menu with string values
64     BG_PARAMETER_COLOR_RGB,   //!< RGB Color
65     BG_PARAMETER_COLOR_RGBA,  //!< RGBA Color
66     BG_PARAMETER_FONT,        //!< Font (contains fontconfig compatible fontname)
67     BG_PARAMETER_DEVICE,      //!< Device
68     BG_PARAMETER_FILE,        //!< File
69     BG_PARAMETER_DIRECTORY,   //!< Directory
70     BG_PARAMETER_MULTI_MENU,  //!< Menu with config- and infobutton
71     BG_PARAMETER_MULTI_LIST,  //!< List with config- and infobutton
72     BG_PARAMETER_MULTI_CHAIN, //!< Several subitems (including suboptions) can be arranged in a chain
73     BG_PARAMETER_TIME,        //!< Time
74     BG_PARAMETER_POSITION,    //!< Position (x/y coordinates, scaled 0..1)
75     BG_PARAMETER_BUTTON,      //!< Pressing the button causes set_parameter to be called with NULL value
76   } bg_parameter_type_t;
77 
78 /** \ingroup parameter
79  * \brief Container for a parameter value
80  */
81 
82 typedef union
83   {
84   double  val_f; //!< For BG_PARAMETER_FLOAT and BG_PARAMETER_SLIDER_FLOAT
85   int     val_i; //!< For BG_PARAMETER_CHECKBUTTON, BG_PARAMETER_INT and BG_PARAMETER_SLIDER_INT
86   char *  val_str; //!< For BG_PARAMETER_STRING, BG_PARAMETER_STRING_HIDDEN, BG_PARAMETER_STRINGLIST, BG_PARAMETER_FONT, BG_PARAMETER_FILE, BG_PARAMETER_DIRECTORY, BG_PARAMETER_MULTI_MENU, BG_PARAMETER_MULTI_LIST
87   float val_color[4];  //!< RGBA values (0.0..1.0) for BG_PARAMETER_COLOR_RGB and BG_PARAMETER_COLOR_RGBA
88   gavl_time_t val_time; //!< For BG_PARAMETER_TIME
89   double val_pos[2];     //!< For BG_PARAMETER_POSITION
90   } bg_parameter_value_t;
91 
92 /* Flags */
93 
94 /** \ingroup parameter
95  */
96 
97 #define BG_PARAMETER_SYNC         (1<<0) //!< Apply the value whenever the widgets value changes
98 
99 /** \ingroup parameter
100  */
101 
102 #define BG_PARAMETER_HIDE_DIALOG  (1<<1) //!< Don't make a configuration widget (for objects, which change values themselves)
103 
104 /** \ingroup parameter
105  */
106 
107 #define BG_PARAMETER_NO_SORT      (1<<2) //!< Don't make a list sortable
108 
109 /** \ingroup parameter
110  */
111 
112 #define BG_PARAMETER_PLUGIN      (1<<3) //!< Parameter refers to a plugin
113 
114 /** \ingroup parameter
115  */
116 
117 #define BG_PARAMETER_OWN_SECTION (1<<4) //!< For parameters of the type BG_PARAMETER_SECTION: Following parameters should be stored in an own section
118 
119 /** \ingroup parameter
120  *  \brief Typedef for parmeter description
121  */
122 
123 #define BG_PARAMETER_GLOBAL_PRESET (1<<5) //!< For parameters of the type BG_PARAMETER_SECTION: There should be one preset for all following sections
124 
125 
126 typedef struct bg_parameter_info_s bg_parameter_info_t;
127 
128 /** \ingroup parameter
129  *  \brief Parmeter description
130  *
131  *  Usually, parameter infos are passed around as NULL-terminated arrays.
132  */
133 
134 struct bg_parameter_info_s
135   {
136   char * name; //!< Unique name. Can contain alphanumeric characters plus underscore.
137   char * long_name; //!< Long name (for labels)
138   char * opt; //!< ultrashort name (optional for commandline). If missing, the name will be used.
139 
140   char * gettext_domain; //!< First argument for bindtextdomain(). In an array, it's valid for subsequent entries too.
141   char * gettext_directory; //!< Second argument for bindtextdomain(). In an array, it's valid for subsequent entries too.
142 
143   bg_parameter_type_t type; //!< Type
144 
145   int flags; //!< Mask of BG_PARAMETER_* defines
146 
147   bg_parameter_value_t val_default; //!< Default value
148   bg_parameter_value_t val_min; //!< Minimum value (for arithmetic types)
149   bg_parameter_value_t val_max; //!< Maximum value (for arithmetic types)
150 
151   /* Names which can be passed to set_parameter (NULL terminated) */
152 
153   char const * const * multi_names; //!< Names for multi option parameters (NULL terminated)
154 
155   /* Long names are optional, if they are NULL,
156      the short names are used */
157 
158   char const * const * multi_labels; //!< Optional labels for multi option parameters
159   char const * const * multi_descriptions; //!< Optional descriptions (will be displayed by info buttons)
160 
161   /*
162    *  These are parameters for each codec.
163    *  The name members of these MUST be unique with respect to the rest
164    *  of the parameters passed to the same set_parameter func
165    */
166 
167   struct bg_parameter_info_s const * const * multi_parameters; //!< Parameters for each option. The name members of these MUST be unique with respect to the rest of the parameters passed to the same set_parameter func
168 
169   int num_digits; //!< Number of digits for floating point parameters
170 
171   char * help_string; //!< Help strings for tooltips or --help option
172 
173   char * preset_path; //!< Path for storing configuration presets
174 
175   char ** multi_names_nc; //!< When allocating dynamically, use this instead of multi_names and call \ref bg_parameter_info_set_const_ptrs at the end
176 
177   char ** multi_labels_nc; //!< When allocating dynamically, use this instead of multi_labels and call \ref bg_parameter_info_set_const_ptrs at the end
178 
179   char ** multi_descriptions_nc; //!< When allocating dynamically, use this instead of multi_descriptions and call \ref bg_parameter_info_set_const_ptrs at the end
180 
181   struct bg_parameter_info_s ** multi_parameters_nc; //!< When allocating dynamically, use this instead of multi_parameters and call \ref bg_parameter_info_set_const_ptrs at the end
182 
183   };
184 
185 /* Prototype for setting/getting parameters */
186 
187 /*
188  *  NOTE: All applications MUST call a bg_set_parameter_func with
189  *  a NULL name argument to signal, that all parameters are set now
190  */
191 
192 /** \ingroup parameter
193  *  \brief Generic prototype for setting parameters in a module
194  *  \param data Instance
195  *  \param name Name of the parameter
196  *  \param v Value
197  *
198  *  This function is usually called from "Apply" buttons in config dialogs.
199  *  It's called subsequently for all defined püarameters. After that, it *must*
200  *  be called with a NULL argument for the name to signal, that all parameters
201  *  are set. Modules can do some additional setup stuff then. If not, the name == NULL
202  *  case must be handled nevertheless.
203  */
204 
205 typedef void (*bg_set_parameter_func_t)(void * data, const char * name,
206                                         const bg_parameter_value_t * v);
207 
208 /** \ingroup parameter
209  *  \brief Generic prototype for getting parameters from a module
210  *  \param data Instance
211  *  \param name Name of the parameter
212  *  \param v Value
213  *
214  *  \returns 1 if a parameter was found and set, 0 else.
215  *
216  *  Provide this function, if your module changes parameters by itself.
217  *  Set the \ref BG_PARAMETER_HIDE_DIALOG to prevent building config
218  *  dialogs for those parameters.
219  */
220 
221 typedef int (*bg_get_parameter_func_t)(void * data, const char * name,
222                                        bg_parameter_value_t * v);
223 
224 /** \ingroup parameter
225  *  \brief Copy a single parameter info
226  *  \param src Source
227  *  \param dst Destination
228  */
229 
230 void bg_parameter_info_copy(bg_parameter_info_t * dst,
231                             const bg_parameter_info_t * src);
232 
233 /** \ingroup parameter
234  *  \brief Copy a NULL terminated parameter array
235  *  \param src Source array
236  *
237  *  \returns A newly allocated parameter array, whose contents are copied from src.
238  *
239  *  Use \ref bg_parameter_info_destroy_array to free the returned array.
240  */
241 
242 bg_parameter_info_t *
243 bg_parameter_info_copy_array(const bg_parameter_info_t * src);
244 
245 /** \ingroup parameter
246  *  \brief Set the const pointers of a dynamically allocated parameter info
247  *  \param info A parameter info
248  *
249  *  This copied the adresses of the *_nc pointers to their constant equivalents.
250  *  Use this for each parameter in routines, which dynamically allocate parameter infos.
251  */
252 
253 void
254 bg_parameter_info_set_const_ptrs(bg_parameter_info_t * info);
255 
256 /** \ingroup parameter
257  *  \brief Free a NULL terminated parameter array
258  *  \param info Parameter array
259  */
260 
261 void bg_parameter_info_destroy_array(bg_parameter_info_t * info);
262 
263 /** \ingroup parameter
264  *  \brief Copy a parameter value
265  *  \param dst Destination
266  *  \param src Source
267  *  \param info Parameter description
268  *
269  *  Make sure, that dst is either memset to 0 or contains
270  *  data, which was created by \ref bg_parameter_value_copy
271  */
272 
273 void bg_parameter_value_copy(bg_parameter_value_t * dst,
274                              const bg_parameter_value_t * src,
275                              const bg_parameter_info_t * info);
276 
277 /** \ingroup parameter
278  *  \brief Free a parameter value
279  *  \param val A parameter value
280  *  \param type Type of the parameter
281  */
282 
283 void bg_parameter_value_free(bg_parameter_value_t * val,
284                              bg_parameter_type_t type);
285 
286 
287 /** \ingroup parameter
288  *  \brief Concatenate multiple arrays into one
289  *  \param srcs NULL terminated array of source arrays
290  *  \returns A newly allocated array
291  */
292 
293 
294 bg_parameter_info_t *
295 bg_parameter_info_concat_arrays(bg_parameter_info_t const ** srcs);
296 
297 /** \ingroup parameter
298  *  \brief Get the index for a multi-options parameter
299  *  \param info A parameter info
300  *  \param val The value
301  *  \returns The index of val in the multi_names array
302  *
303  *  If val does not occur in the multi_names[] array,
304  *  try the default value. If that fails as well, return 0.
305  */
306 
307 int bg_parameter_get_selected(const bg_parameter_info_t * info,
308                               const char * val);
309 
310 
311 /** \ingroup parameter
312  *  \brief Find a parameter info
313  *  \param info A parameter info
314  *  \param name The name of the the parameter
315  *  \returns Parameter info matching name or NULL
316  *
317  *  This function looks for a parameter info with the
318  *  given name in an array or parameters. Sub-parameters
319  *  are also searched.
320  */
321 
322 const bg_parameter_info_t *
323 bg_parameter_find(const bg_parameter_info_t * info,
324                   const char * name);
325 
326 
327 /** \ingroup parameter
328  *  \brief Convert a libxml2 node into a parameter array
329  *  \param xml_doc Pointer to the xml document
330  *  \param xml_parameters Pointer to the xml node containing the parameters
331  *  \returns A newly allocated array
332  *
333  *  See the libxml2 documentation for more infos
334  */
335 
336 
337 bg_parameter_info_t * bg_xml_2_parameters(xmlDocPtr xml_doc,
338                                           xmlNodePtr xml_parameters);
339 
340 /** \ingroup parameter
341  *  \brief Convert a parameter array into a libxml2 node
342  *  \param info Parameter array
343  *  \param xml_parameters Pointer to the xml node for the parameters
344  *
345  *  See the libxml2 documentation for more infos
346  */
347 
348 
349 void
350 bg_parameters_2_xml(const bg_parameter_info_t * info, xmlNodePtr xml_parameters);
351 
352 /** \ingroup parameter
353  *  \brief Dump a parameter array into a xml file
354  *  \param info Parameter array
355  *  \param filename File to dump to
356  *
357  *  Used for debugging
358  */
359 
360 void
361 bg_parameters_dump(const bg_parameter_info_t * info, const char * filename);
362 
363 
364 #endif /* __BG_PARAMETER_H_ */
365 
366