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