dav1d: picture_Clone the output picture
[vlc.git] / src / config / core.c
blobb1904e1f644998dedb22c91a906ccbf80f097865
1 /*****************************************************************************
2 * core.c management of the modules configuration
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <vlc_common.h>
29 #include <vlc_actions.h>
30 #include <vlc_modules.h>
31 #include <vlc_plugin.h>
33 #include "vlc_configuration.h"
35 #include <errno.h>
36 #include <assert.h>
38 #include "configuration.h"
39 #include "modules/modules.h"
41 vlc_rwlock_t config_lock = VLC_STATIC_RWLOCK;
42 bool config_dirty = false;
44 static inline char *strdupnull (const char *src)
46 return src ? strdup (src) : NULL;
49 int config_GetType(const char *psz_name)
51 module_config_t *p_config = config_FindConfig(psz_name);
53 /* sanity checks */
54 if( !p_config )
56 return 0;
59 switch( CONFIG_CLASS(p_config->i_type) )
61 case CONFIG_ITEM_FLOAT:
62 return VLC_VAR_FLOAT;
63 case CONFIG_ITEM_INTEGER:
64 return VLC_VAR_INTEGER;
65 case CONFIG_ITEM_BOOL:
66 return VLC_VAR_BOOL;
67 case CONFIG_ITEM_STRING:
68 return VLC_VAR_STRING;
69 default:
70 return 0;
74 bool config_IsSafe( const char *name )
76 module_config_t *p_config = config_FindConfig( name );
77 return p_config != NULL && p_config->b_safe;
80 int64_t config_GetInt(const char *psz_name)
82 module_config_t *p_config = config_FindConfig( psz_name );
84 /* sanity checks */
85 assert(p_config != NULL);
86 assert(IsConfigIntegerType(p_config->i_type));
88 int64_t val;
90 vlc_rwlock_rdlock (&config_lock);
91 val = p_config->value.i;
92 vlc_rwlock_unlock (&config_lock);
93 return val;
96 float config_GetFloat(const char *psz_name)
98 module_config_t *p_config;
100 p_config = config_FindConfig( psz_name );
102 /* sanity checks */
103 assert(p_config != NULL);
104 assert(IsConfigFloatType(p_config->i_type));
106 float val;
108 vlc_rwlock_rdlock (&config_lock);
109 val = p_config->value.f;
110 vlc_rwlock_unlock (&config_lock);
111 return val;
114 char *config_GetPsz(const char *psz_name)
116 module_config_t *p_config;
118 p_config = config_FindConfig( psz_name );
120 /* sanity checks */
121 assert(p_config != NULL);
122 assert(IsConfigStringType (p_config->i_type));
124 /* return a copy of the string */
125 vlc_rwlock_rdlock (&config_lock);
126 char *psz_value = strdupnull (p_config->value.psz);
127 vlc_rwlock_unlock (&config_lock);
129 return psz_value;
132 void config_PutPsz(const char *psz_name, const char *psz_value)
134 module_config_t *p_config = config_FindConfig( psz_name );
137 /* sanity checks */
138 assert(p_config != NULL);
139 assert(IsConfigStringType(p_config->i_type));
141 char *str, *oldstr;
142 if ((psz_value != NULL) && *psz_value)
143 str = strdup (psz_value);
144 else
145 str = NULL;
147 vlc_rwlock_wrlock (&config_lock);
148 oldstr = (char *)p_config->value.psz;
149 p_config->value.psz = str;
150 config_dirty = true;
151 vlc_rwlock_unlock (&config_lock);
153 free (oldstr);
156 void config_PutInt(const char *psz_name, int64_t i_value )
158 module_config_t *p_config = config_FindConfig( psz_name );
160 /* sanity checks */
161 assert(p_config != NULL);
162 assert(IsConfigIntegerType(p_config->i_type));
164 if (i_value < p_config->min.i)
165 i_value = p_config->min.i;
166 if (i_value > p_config->max.i)
167 i_value = p_config->max.i;
169 vlc_rwlock_wrlock (&config_lock);
170 p_config->value.i = i_value;
171 config_dirty = true;
172 vlc_rwlock_unlock (&config_lock);
175 void config_PutFloat(const char *psz_name, float f_value)
177 module_config_t *p_config = config_FindConfig( psz_name );
179 /* sanity checks */
180 assert(p_config != NULL);
181 assert(IsConfigFloatType(p_config->i_type));
183 /* if f_min == f_max == 0, then do not use them */
184 if ((p_config->min.f == 0.f) && (p_config->max.f == 0.f))
186 else if (f_value < p_config->min.f)
187 f_value = p_config->min.f;
188 else if (f_value > p_config->max.f)
189 f_value = p_config->max.f;
191 vlc_rwlock_wrlock (&config_lock);
192 p_config->value.f = f_value;
193 config_dirty = true;
194 vlc_rwlock_unlock (&config_lock);
197 ssize_t config_GetIntChoices(const char *name,
198 int64_t **restrict values, char ***restrict texts)
200 *values = NULL;
201 *texts = NULL;
203 module_config_t *cfg = config_FindConfig(name);
204 assert(cfg != NULL);
206 size_t count = cfg->list_count;
207 if (count == 0)
209 if (module_Map(NULL, cfg->owner))
211 errno = EIO;
212 return -1;
215 if (cfg->list.i_cb == NULL)
216 return 0;
217 return cfg->list.i_cb(name, values, texts);
220 int64_t *vals = vlc_alloc (count, sizeof (*vals));
221 char **txts = vlc_alloc (count, sizeof (*txts));
222 if (vals == NULL || txts == NULL)
224 errno = ENOMEM;
225 goto error;
228 for (size_t i = 0; i < count; i++)
230 vals[i] = cfg->list.i[i];
231 /* FIXME: use module_gettext() instead */
232 txts[i] = strdup ((cfg->list_text[i] != NULL)
233 ? vlc_gettext (cfg->list_text[i]) : "");
234 if (unlikely(txts[i] == NULL))
236 for (int j = i - 1; j >= 0; --j)
237 free(txts[j]);
238 errno = ENOMEM;
239 goto error;
243 *values = vals;
244 *texts = txts;
245 return count;
246 error:
248 free(vals);
249 free(txts);
250 return -1;
254 static ssize_t config_ListModules (const char *cap, char ***restrict values,
255 char ***restrict texts)
257 module_t **list;
258 ssize_t n = module_list_cap (&list, cap);
259 if (unlikely(n < 0))
261 *values = *texts = NULL;
262 return n;
265 char **vals = malloc ((n + 2) * sizeof (*vals));
266 char **txts = malloc ((n + 2) * sizeof (*txts));
267 if (!vals || !txts)
269 free (vals);
270 free (txts);
271 *values = *texts = NULL;
272 return -1;
275 ssize_t i = 0;
277 vals[i] = strdup ("any");
278 txts[i] = strdup (_("Automatic"));
279 if (!vals[i] || !txts[i])
280 goto error;
282 ++i;
283 for (; i <= n; i++)
285 vals[i] = strdup (module_get_object (list[i - 1]));
286 txts[i] = strdup (module_gettext (list[i - 1],
287 module_get_name (list[i - 1], true)));
288 if( !vals[i] || !txts[i])
289 goto error;
291 vals[i] = strdup ("none");
292 txts[i] = strdup (_("Disable"));
293 if( !vals[i] || !txts[i])
294 goto error;
296 *values = vals;
297 *texts = txts;
298 module_list_free (list);
299 return i + 1;
301 error:
302 for (ssize_t j = 0; j <= i; ++j)
304 free (vals[j]);
305 free (txts[j]);
307 free(vals);
308 free(txts);
309 module_list_free (list);
310 *values = *texts = NULL;
311 return -1;
314 ssize_t config_GetPszChoices(const char *name,
315 char ***restrict values, char ***restrict texts)
317 *values = *texts = NULL;
319 module_config_t *cfg = config_FindConfig(name);
320 if (cfg == NULL)
322 errno = ENOENT;
323 return -1;
326 switch (cfg->i_type)
328 case CONFIG_ITEM_MODULE:
329 return config_ListModules (cfg->psz_type, values, texts);
330 default:
331 if (!IsConfigStringType (cfg->i_type))
333 errno = EINVAL;
334 return -1;
336 break;
339 size_t count = cfg->list_count;
340 if (count == 0)
342 if (module_Map(NULL, cfg->owner))
344 errno = EIO;
345 return -1;
348 if (cfg->list.psz_cb == NULL)
349 return 0;
350 return cfg->list.psz_cb(name, values, texts);
353 char **vals = malloc (sizeof (*vals) * count);
354 char **txts = malloc (sizeof (*txts) * count);
355 if (!vals || !txts)
357 free (vals);
358 free (txts);
359 errno = ENOMEM;
360 return -1;
363 size_t i;
364 for (i = 0; i < count; i++)
366 vals[i] = strdup ((cfg->list.psz[i] != NULL) ? cfg->list.psz[i] : "");
367 /* FIXME: use module_gettext() instead */
368 txts[i] = strdup ((cfg->list_text[i] != NULL)
369 ? vlc_gettext (cfg->list_text[i]) : "");
370 if (!vals[i] || !txts[i])
371 goto error;
374 *values = vals;
375 *texts = txts;
376 return count;
378 error:
379 for (size_t j = 0; j <= i; ++j)
381 free (vals[j]);
382 free (txts[j]);
384 free(vals);
385 free(txts);
386 errno = ENOMEM;
387 return -1;
390 static int confcmp (const void *a, const void *b)
392 const module_config_t *const *ca = a, *const *cb = b;
394 return strcmp ((*ca)->psz_name, (*cb)->psz_name);
397 static int confnamecmp (const void *key, const void *elem)
399 const module_config_t *const *conf = elem;
401 return strcmp (key, (*conf)->psz_name);
404 static struct
406 module_config_t **list;
407 size_t count;
408 } config = { NULL, 0 };
411 * Index the configuration items by name for faster lookups.
413 int config_SortConfig (void)
415 vlc_plugin_t *p;
416 size_t nconf = 0;
418 for (p = vlc_plugins; p != NULL; p = p->next)
419 nconf += p->conf.size;
421 module_config_t **clist = vlc_alloc (nconf, sizeof (*clist));
422 if (unlikely(clist == NULL))
423 return VLC_ENOMEM;
425 nconf = 0;
426 for (p = vlc_plugins; p != NULL; p = p->next)
428 module_config_t *item, *end;
430 for (item = p->conf.items, end = item + p->conf.size;
431 item < end;
432 item++)
434 if (!CONFIG_ITEM(item->i_type))
435 continue; /* ignore hints */
436 clist[nconf++] = item;
440 qsort (clist, nconf, sizeof (*clist), confcmp);
442 config.list = clist;
443 config.count = nconf;
444 return VLC_SUCCESS;
447 void config_UnsortConfig (void)
449 module_config_t **clist;
451 clist = config.list;
452 config.list = NULL;
453 config.count = 0;
455 free (clist);
458 module_config_t *config_FindConfig(const char *name)
460 if (unlikely(name == NULL))
461 return NULL;
463 module_config_t *const *p;
464 p = bsearch (name, config.list, config.count, sizeof (*p), confnamecmp);
465 return p ? *p : NULL;
469 * Destroys an array of configuration items.
470 * \param config start of array of items
471 * \param confsize number of items in the array
473 void config_Free (module_config_t *tab, size_t confsize)
475 for (size_t j = 0; j < confsize; j++)
477 module_config_t *p_item = &tab[j];
479 if (IsConfigStringType (p_item->i_type))
481 free (p_item->value.psz);
482 if (p_item->list_count)
483 free (p_item->list.psz);
486 free (p_item->list_text);
489 free (tab);
492 void config_ResetAll(void)
494 vlc_rwlock_wrlock (&config_lock);
495 for (vlc_plugin_t *p = vlc_plugins; p != NULL; p = p->next)
497 for (size_t i = 0; i < p->conf.size; i++ )
499 module_config_t *p_config = p->conf.items + i;
501 if (IsConfigIntegerType (p_config->i_type))
502 p_config->value.i = p_config->orig.i;
503 else
504 if (IsConfigFloatType (p_config->i_type))
505 p_config->value.f = p_config->orig.f;
506 else
507 if (IsConfigStringType (p_config->i_type))
509 free ((char *)p_config->value.psz);
510 p_config->value.psz =
511 strdupnull (p_config->orig.psz);
515 vlc_rwlock_unlock (&config_lock);