]> git.sesse.net Git - vlc/blob - src/modules/entry.c
63e668fd9b7533a2fa586e61deee7dc7c7ddab1a
[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 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <vlc/vlc.h>
26 #include <assert.h>
27 #include <stdarg.h>
28
29 #include "modules/modules.h"
30 #include "config/configuration.h"
31 #include "libvlc.h"
32
33 static const char default_name[] = "unnamed";
34
35 module_t *vlc_module_create (vlc_object_t *obj)
36 {
37     module_t *module =
38         (module_t *)vlc_custom_create (obj, sizeof (module_t),
39                                        VLC_OBJECT_MODULE, "module");
40     if (module == NULL)
41         return NULL;
42
43     module->b_reentrant = module->b_unloadable = true;
44     module->psz_object_name = strdup( default_name );
45     module->psz_longname = default_name;
46     module->psz_capability = (char*)"";
47     module->i_score = 1;
48     module->i_config_items = module->i_bool_items = 0;
49
50     return module;
51 }
52
53
54 module_t *vlc_submodule_create (module_t *module)
55 {
56     assert (module != NULL);
57     assert (!module->b_submodule); // subsubmodules are not supported
58
59     module_t *submodule =
60         (module_t *)vlc_custom_create (VLC_OBJECT (module), sizeof (module_t),
61                                        VLC_OBJECT_MODULE, "submodule");
62     if (submodule == NULL)
63         return NULL;
64
65     vlc_object_attach (submodule, module);
66     submodule->b_submodule = true;
67
68     /* Muahahaha! Heritage! Polymorphism! Ugliness!! */
69     memcpy (submodule->pp_shortcuts, module->pp_shortcuts,
70             sizeof (submodule->pp_shortcuts));
71
72     submodule->psz_object_name = strdup( module->psz_object_name );
73     submodule->psz_shortname = module->psz_shortname;
74     submodule->psz_longname = module->psz_longname;
75     submodule->psz_capability = module->psz_capability;
76     submodule->i_score = module->i_score;
77     submodule->i_cpu = module->i_cpu;
78     return submodule;
79 }
80
81
82 int vlc_module_set (module_t *module, int propid, void *value)
83 {
84     switch (propid)
85     {
86         case VLC_MODULE_CPU_REQUIREMENT:
87             assert (!module->b_submodule);
88             module->i_cpu |= (intptr_t)value;
89             break;
90
91         case VLC_MODULE_SHORTCUT:
92         {
93             unsigned i;
94             for (i = 0; module->pp_shortcuts[i] != NULL; i++);
95             if (i >= (MODULE_SHORTCUT_MAX - 1))
96                 return VLC_ENOMEM;
97
98             module->pp_shortcuts[i] = (char *)value;
99             break;
100         }
101
102         case VLC_MODULE_SHORTNAME:
103             module->psz_shortname = (char *)value;
104             break;
105
106         case VLC_MODULE_DESCRIPTION:
107             module->psz_longname = (char *)value;
108             break;
109
110         case VLC_MODULE_HELP:
111             module->psz_help = (char *)value;
112             break;
113
114         case VLC_MODULE_CAPABILITY:
115             module->psz_capability = (char *)value;
116             break;
117
118         case VLC_MODULE_SCORE:
119             module->i_score = (intptr_t)value;
120             break;
121
122         case VLC_MODULE_CB_OPEN:
123             module->pf_activate = (int (*) (vlc_object_t *))value;
124             break;
125
126         case VLC_MODULE_CB_CLOSE:
127             module->pf_deactivate = (void (*) (vlc_object_t *))value;
128             break;
129
130         case VLC_MODULE_UNLOADABLE:
131             module->b_unloadable = (value != NULL);
132             break;
133
134         case VLC_MODULE_NAME:
135             free( module->psz_object_name );
136             module->psz_object_name = strdup( (char *)value );
137             module->pp_shortcuts[0] = (char *)value;
138             if (module->psz_longname == default_name)
139                 module->psz_longname = (char *)value;
140             break;
141
142         case VLC_MODULE_PROGRAM:
143             msg_Warn (module, "deprecated module property %d", propid);
144             break;
145
146         default:
147             msg_Err (module, "unknown module property %d", propid);
148             msg_Err (module, "LibVLC might be too old to use this module.");
149             return VLC_EGENERIC;
150     }
151     return 0;
152 }
153
154 module_config_t *vlc_config_create (module_t *module, int type)
155 {
156     unsigned confsize = module->confsize;
157     module_config_t *tab = module->p_config;
158
159     if ((confsize & 0xf) == 0)
160     {
161         tab = realloc (tab, (confsize + 17) * sizeof (*tab));
162         if (tab == NULL)
163             return NULL;
164
165         module->p_config = tab;
166     }
167
168     memset (tab + confsize, 0, sizeof (tab[confsize]));
169     tab[confsize].i_type = type;
170     tab[confsize].p_lock = &module->object_lock;
171
172     if (type & CONFIG_ITEM)
173     {
174         module->i_config_items++;
175         if (type == CONFIG_ITEM_BOOL)
176             module->i_bool_items++;
177     }
178
179     module->confsize++;
180     return tab + confsize;
181 }
182
183 int vlc_config_set (module_config_t *restrict item, int id, ...)
184 {
185     int ret = -1;
186     va_list ap;
187
188     assert (item != NULL);
189     va_start (ap, id);
190
191     switch (id)
192     {
193         case VLC_CONFIG_NAME:
194         {
195             const char *name = va_arg (ap, const char *);
196             vlc_callback_t cb = va_arg (ap, vlc_callback_t);
197
198             assert (name != NULL);
199             item->psz_name = strdup (name);
200             item->pf_callback = cb;
201             ret = 0;
202             break;
203         }
204
205         case VLC_CONFIG_DESC:
206         {
207             const char *text = va_arg (ap, const char *);
208             const char *longtext = va_arg (ap, const char *);
209
210             item->psz_text = text ? strdup ( _(text)) : NULL;
211             item->psz_longtext = longtext ? strdup ( _(longtext)) : NULL;
212             ret = 0;
213             break;
214         }
215
216         case VLC_CONFIG_VALUE:
217         {
218             if (IsConfigIntegerType (item->i_type))
219             {
220                 item->orig.i = item->saved.i =
221                 item->value.i = va_arg (ap, int);
222                 ret = 0;
223             }
224             else
225             if (IsConfigFloatType (item->i_type))
226             {
227                 item->orig.f = item->saved.f =
228                 item->value.f = va_arg (ap, double);
229                 ret = 0;
230             }
231             else
232             if (IsConfigStringType (item->i_type))
233             {
234                 const char *value = va_arg (ap, const char *);
235                 item->value.psz = value ? strdup (value) : NULL;
236                 item->orig.psz = value ? strdup (value) : NULL;
237                 item->saved.psz = value ? strdup (value) : NULL;
238                 ret = 0;
239             }
240             break;
241         }
242
243         case VLC_CONFIG_RANGE:
244         {
245             if (IsConfigIntegerType (item->i_type))
246             {
247                 item->min.i = va_arg (ap, int);
248                 item->max.i = va_arg (ap, int);
249                 ret = 0;
250             }
251             else
252             if (IsConfigFloatType (item->i_type))
253             {
254                 item->min.f = va_arg (ap, double);
255                 item->max.f = va_arg (ap, double);
256                 ret = 0;
257             }
258             break;
259         }
260
261         case VLC_CONFIG_ADVANCED:
262             item->b_advanced = true;
263             ret = 0;
264             break;
265
266         case VLC_CONFIG_VOLATILE:
267             item->b_unsaveable = true;
268             ret = 0;
269             break;
270
271         case VLC_CONFIG_PERSISTENT:
272             item->b_autosave = true;
273             ret = 0;
274             break;
275
276         case VLC_CONFIG_RESTART:
277             item->b_restart = true;
278             ret = 0;
279             break;
280
281         case VLC_CONFIG_PRIVATE:
282             item->b_internal = true;
283             ret = 0;
284             break;
285
286         case VLC_CONFIG_REMOVED:
287             item->b_removed = true;
288             ret = 0;
289             break;
290
291         case VLC_CONFIG_CAPABILITY:
292         {
293             const char *cap = va_arg (ap, const char *);
294             item->psz_type = cap ? strdup (cap) : NULL;
295             ret = 0;
296             break;
297         }
298
299         case VLC_CONFIG_SHORTCUT:
300             item->i_short = va_arg (ap, int);
301             ret = 0;
302             break;
303
304         case VLC_CONFIG_LIST:
305         {
306             size_t len = va_arg (ap, size_t);
307             char **dtext = malloc (sizeof (char *) * (len + 1));
308
309             if (dtext == NULL)
310                 break;
311
312             /* Copy values */
313             if (IsConfigIntegerType (item->i_type))
314             {
315                 const int *src = va_arg (ap, const int *);
316                 int *dst = malloc (sizeof (int) * (len + 1));
317
318                 if (dst != NULL)
319                 {
320                     memcpy (dst, src, sizeof (int) * len);
321                     dst[len] = 0;
322                 }
323                 item->pi_list = dst;
324             }
325             else
326 #if 0
327             if (IsConfigFloatType (item->i_type))
328             {
329                 const float *src = va_arg (ap, const float *);
330                 float *dst = malloc (sizeof (float) * (len + 1));
331
332                 if (dst != NULL)
333                 {
334                     memcpy (dst, src, sizeof (float) * len);
335                     dst[len] = 0.;
336                 }
337                 item->pf_list = dst;
338             }
339             else
340 #endif
341             if (IsConfigStringType (item->i_type))
342             {
343                 const char *const *src = va_arg (ap, const char *const *);
344                 char **dst = malloc (sizeof (char *) * (len + 1));
345
346                 if (dst != NULL)
347                 {
348                     for (size_t i = 0; i < len; i++)
349                         dst[i] = src[i] ? strdup (src[i]) : NULL;
350                     dst[len] = NULL;
351                 }
352                 item->ppsz_list = dst;
353             }
354             else
355                 break;
356
357             /* Copy textual descriptions */
358             const char *const *text = va_arg (ap, const char *const *);
359             if (text != NULL)
360             {
361                 for (size_t i = 0; i < len; i++)
362                     dtext[i] = text[i] ? strdup ( _(text[i])) : NULL;
363
364                 dtext[len] = NULL;
365                 item->ppsz_list_text = dtext;
366             }
367             else
368             {
369                 free (dtext);
370                 item->ppsz_list_text = NULL;
371             }
372
373             item->i_list = len;
374             item->pf_update_list = va_arg (ap, vlc_callback_t);
375             ret = 0;
376             break;
377         }
378
379         case VLC_CONFIG_ADD_ACTION:
380         {
381             vlc_callback_t cb = va_arg (ap, vlc_callback_t), *tabcb;
382             const char *name = va_arg (ap, const char *);
383             char **tabtext;
384
385             tabcb = realloc (item->ppf_action,
386                              (item->i_action + 2) * sizeof (cb));
387             if (tabcb == NULL)
388                 break;
389             item->ppf_action = tabcb;
390             tabcb[item->i_action] = cb;
391             tabcb[item->i_action + 1] = NULL;
392
393             tabtext = realloc (item->ppsz_action_text,
394                                (item->i_action + 2) * sizeof (name));
395             if (tabtext == NULL)
396                 break;
397             item->ppsz_action_text = tabtext;
398
399             if (name)
400                 tabtext[item->i_action] = strdup ( _(name));
401             else
402                 tabtext[item->i_action] = NULL;
403             tabtext[item->i_action + 1] = NULL;
404
405             item->i_action++;
406             ret = 0;
407             break;
408         }
409
410         case VLC_CONFIG_OLDNAME:
411         {
412             const char *oldname = va_arg (ap, const char *);
413             item->psz_oldname = oldname ? strdup (oldname) : NULL;
414             ret = 0;
415             break;
416         }
417
418         case VLC_CONFIG_SAFE:
419             item->b_safe = true;
420             ret = 0;
421             break;
422     }
423
424     va_end (ap);
425     return ret;
426 }