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