]> git.sesse.net Git - vlc/blob - src/modules/entry.c
Add action through vlc_config_set
[vlc] / src / modules / entry.c
1 /*****************************************************************************
2  * entry.c : Callbacks for module entry point
3  *****************************************************************************
4  * Copyright (C) 2001-2007 the VideoLAN team
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #include <vlc/vlc.h>
22 #include <assert.h>
23 #include <stdarg.h>
24
25 #include "modules/modules.h"
26 #include "config/config.h"
27 #include "libvlc.h"
28
29 static const char default_name[] = "unnamed";
30
31 module_t *vlc_module_create (vlc_object_t *obj)
32 {
33     module_t *module =
34         (module_t *)vlc_custom_create (obj, sizeof (module_t),
35                                        VLC_OBJECT_MODULE, "module");
36     if (module == NULL)
37         return NULL;
38
39     module->b_reentrant = module->b_unloadable = VLC_TRUE;
40     module->psz_object_name = module->psz_longname = default_name;
41     module->psz_capability = "";
42     module->i_score = 1;
43     return module;
44 }
45
46
47 module_t *vlc_submodule_create (module_t *module)
48 {
49     assert (module != NULL);
50     assert (!module->b_submodule); // subsubmodules are not supported
51
52     module_t *submodule =
53         (module_t *)vlc_custom_create (VLC_OBJECT (module), sizeof (module_t),
54                                        VLC_OBJECT_MODULE, "submodule");
55     if (submodule == NULL)
56         return NULL;
57
58     vlc_object_attach (submodule, module);
59     submodule->b_submodule = VLC_TRUE;
60
61     /* Muahahaha! Heritage! Polymorphism! Ugliness!! */
62     memcpy (submodule->pp_shortcuts, module->pp_shortcuts,
63             sizeof (submodule->pp_shortcuts));
64
65     submodule->psz_object_name = module->psz_object_name;
66     submodule->psz_shortname = module->psz_shortname;
67     submodule->psz_longname = module->psz_longname;
68     submodule->psz_capability = module->psz_capability;
69     submodule->i_score = module->i_score;
70     submodule->i_cpu = module->i_cpu;
71     return submodule;
72 }
73
74
75 int vlc_module_set (module_t *module, int propid, void *value)
76 {
77     switch (propid)
78     {
79         case VLC_MODULE_CPU_REQUIREMENT:
80             assert (!module->b_submodule);
81             module->i_cpu |= (intptr_t)value;
82             break;
83
84         case VLC_MODULE_SHORTCUT:
85         {
86             unsigned i;
87             for (i = 0; module->pp_shortcuts[i] != NULL; i++);
88             if (i >= (MODULE_SHORTCUT_MAX - 1))
89                 return VLC_ENOMEM;
90
91             module->pp_shortcuts[i] = (char *)value;
92             break;
93         }
94
95         case VLC_MODULE_SHORTNAME:
96             module->psz_shortname = (char *)value;
97             break;
98
99         case VLC_MODULE_DESCRIPTION:
100             module->psz_longname = (char *)value;
101             break;
102
103         case VLC_MODULE_HELP:
104             module->psz_help = (char *)value;
105             break;
106
107         case VLC_MODULE_CAPABILITY:
108             module->psz_capability = (char *)value;
109             break;
110
111         case VLC_MODULE_SCORE:
112             module->i_score = (intptr_t)value;
113             break;
114
115         case VLC_MODULE_CB_OPEN:
116             module->pf_activate = (int (*) (vlc_object_t *))value;
117             break;
118
119         case VLC_MODULE_CB_CLOSE:
120             module->pf_deactivate = (void (*) (vlc_object_t *))value;
121             break;
122
123         case VLC_MODULE_UNLOADABLE:
124             module->b_unloadable = (value != NULL);
125             break;
126
127         case VLC_MODULE_NAME:
128             module->pp_shortcuts[0] = module->psz_object_name = (char *)value;
129             if (module->psz_longname == default_name)
130                 module->psz_longname = (char *)value;
131             break;
132
133         case VLC_MODULE_PROGRAM:
134             msg_Warn (module, "deprecated module property %d", propid);
135             break;
136
137         default:
138             msg_Err (module, "unknown module property %d", propid);
139             msg_Err (module, "LibVLC might be too old to use this module.");
140             return VLC_EGENERIC;
141     }
142     return 0;
143 }
144
145 module_config_t *vlc_config_create (module_t *module, int type)
146 {
147     unsigned confsize = module->confsize;
148     module_config_t *tab = module->p_config;
149
150     if ((confsize & 0xf) == 0)
151     {
152         tab = realloc (tab, (confsize + 17) * sizeof (*tab));
153         if (tab == NULL)
154             return NULL;
155
156         module->p_config = tab;
157     }
158     module->confsize++;
159
160     memset (tab + confsize, 0, sizeof (tab[confsize]));
161     tab[confsize].i_type = type;
162     tab[confsize].p_lock = &module->object_lock;
163
164     return tab + confsize;
165 }
166
167 int vlc_config_set (module_config_t *restrict item, int id, ...)
168 {
169     int ret = -1;
170     va_list ap;
171
172     assert (item != NULL);
173     va_start (ap, id);
174
175     switch (id)
176     {
177         case VLC_CONFIG_NAME:
178         {
179             const char *name = va_arg (ap, const char *);
180             vlc_callback_t cb = va_arg (ap, vlc_callback_t);
181
182             assert (name != NULL);
183             item->psz_name = strdup (name);
184             item->pf_callback = cb;
185             ret = 0;
186             break;
187         }
188
189         case VLC_CONFIG_DESC:
190         {
191             const char *text = va_arg (ap, const char *);
192             const char *longtext = va_arg (ap, const char *);
193
194             item->psz_text = text ? strdup (gettext (text)) : NULL;
195             item->psz_longtext = longtext ? strdup (gettext (text)) : NULL;
196             ret = 0;
197             break;
198         }
199
200         case VLC_CONFIG_VALUE:
201         {
202             if (IsConfigIntegerType (item->i_type))
203             {
204                 item->orig.i = item->saved.i =
205                 item->value.i = va_arg (ap, int);
206                 ret = 0;
207             }
208             else
209             if (IsConfigFloatType (item->i_type))
210             {
211                 item->orig.f = item->saved.f =
212                 item->value.f = va_arg (ap, double);
213                 ret = 0;
214             }
215             else
216             if (IsConfigStringType (item->i_type))
217             {
218                 const char *value = va_arg (ap, const char *);
219                 item->value.psz = value ? strdup (value) : NULL;
220                 item->orig.psz = value ? strdup (value) : NULL;
221                 item->saved.psz = value ? strdup (value) : NULL;
222                 ret = 0;
223             }
224             break;
225         }
226
227         case VLC_CONFIG_RANGE:
228         {
229             if (IsConfigIntegerType (item->i_type))
230             {
231                 item->min.i = va_arg (ap, int);
232                 item->max.i = va_arg (ap, int);
233                 ret = 0;
234             }
235             else
236             if (IsConfigFloatType (item->i_type))
237             {
238                 item->min.f = va_arg (ap, double);
239                 item->max.f = va_arg (ap, double);
240                 ret = 0;
241             }
242             break;
243         }
244
245         case VLC_CONFIG_ADVANCED:
246             item->b_advanced = VLC_TRUE;
247             ret = 0;
248             break;
249
250         case VLC_CONFIG_VOLATILE:
251             item->b_unsaveable = VLC_TRUE;
252             ret = 0;
253             break;
254
255         case VLC_CONFIG_PERSISTENT:
256             item->b_autosave = VLC_TRUE;
257             ret = 0;
258             break;
259
260         case VLC_CONFIG_RESTART:
261             item->b_restart = VLC_TRUE;
262             ret = 0;
263             break;
264
265         case VLC_CONFIG_PRIVATE:
266             item->b_internal = VLC_TRUE;
267             ret = 0;
268             break;
269
270         case VLC_CONFIG_REMOVED:
271             item->psz_current = "SUPPRESSED";
272             ret = 0;
273             break;
274
275         case VLC_CONFIG_CAPABILITY:
276         {
277             const char *cap = va_arg (ap, const char *);
278             item->psz_type = cap ? strdup (cap) : NULL;
279             ret = 0;
280             break;
281         }
282
283         case VLC_CONFIG_SHORTCUT:
284             item->i_short = va_arg (ap, int);
285             ret = 0;
286             break;
287
288         case VLC_CONFIG_LIST:
289         {
290             size_t len = va_arg (ap, size_t);
291             char **dtext = malloc (sizeof (char *) * (len + 1));
292
293             if (dtext == NULL)
294                 break;
295
296             /* Copy values */
297             if (IsConfigIntegerType (item->i_type))
298             {
299                 const int *src = va_arg (ap, const int *);
300                 int *dst = malloc (sizeof (int) * (len + 1));
301
302                 if (dst != NULL)
303                 {
304                     memcpy (dst, src, sizeof (int) * len);
305                     dst[len] = 0;
306                 }
307                 item->pi_list = dst;
308             }
309             else
310 #if 0
311             if (IsConfigFloatType (item->i_type))
312             {
313                 const float *src = va_arg (ap, const float *);
314                 float *dst = malloc (sizeof (float) * (len + 1));
315
316                 if (dst != NULL)
317                 {
318                     memcpy (dst, src, sizeof (float) * len);
319                     dst[len] = 0.;
320                 }
321                 item->pf_list = dst;
322             }
323             else
324 #endif
325             if (IsConfigStringType (item->i_type))
326             {
327                 const char *const *src = va_arg (ap, const char *const *);
328                 char **dst = malloc (sizeof (char *) * (len + 1));
329
330                 if (dst != NULL)
331                 {
332                     for (size_t i = 0; i < len; i++)
333                         dst[i] = src[i] ? strdup (src[i]) : NULL;
334                     dst[len] = NULL;
335                 }
336                 item->ppsz_list = dst;
337             }
338             else
339                 break;
340
341             /* Copy textual descriptions */
342             const char *const *text = va_arg (ap, const char *const *);
343             if (text != NULL)
344             {
345                 for (size_t i = 0; i < len; i++)
346                     dtext[i] = text[i] ? strdup (gettext (text[i])) : NULL;
347
348                 dtext[len] = NULL;
349                 item->ppsz_list_text = dtext;
350             }
351             else
352                 item->ppsz_list_text = NULL;
353
354             item->i_list = len;
355             ret = 0;
356             break;
357         }
358
359         case VLC_CONFIG_ADD_ACTION:
360         {
361             vlc_callback_t cb = va_arg (ap, vlc_callback_t), *tabcb;
362             const char *name = va_arg (ap, const char *);
363             char **tabtext;
364
365             tabcb = realloc (item->ppf_action,
366                              (item->i_action + 2) * sizeof (cb));
367             if (tabcb == NULL)
368                 break;
369             item->ppf_action = tabcb;
370             tabcb[item->i_action] = cb;
371             tabcb[item->i_action + 1] = NULL;
372
373             tabtext = realloc (item->ppsz_action_text,
374                                (item->i_action + 2) * sizeof (name));
375             if (tabtext == NULL)
376                 break;
377             item->ppsz_action_text = tabtext;
378
379             if (name)
380                 tabtext[item->i_action] = strdup (gettext (name));
381             else
382                 tabtext[item->i_action] = NULL;
383             tabtext[item->i_action + 1] = NULL;
384
385             item->i_action++;
386             ret = 0;
387         }
388     }
389
390     va_end (ap);
391     return ret;
392 }